svg circular animation with radius change - animation

I have a circular animation for 10 secs on an svg circle.
The moment I try to change the r="30"on both the circles, the animation gets effected and last only for 5 secs. I think along with the r value I would have to change the cx and cy values respectively to have a proper dimension and for animation to last for 10secs. Could you please point out what is going wrong?
Here's the link: https://codepen.io/anon/pen/jxREMd
Here's the snippet:
<svg class="progress-circle definite" width="100" height="100">
<defs>
<linearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="transparent"/>
<stop offset="100%" stop-color="black"/>
</linearGradient>
</defs>
<g transform="rotate(-90,50,50)">
<circle class="bg" r="40" cx="50" cy="50" fill="url(#linear)"></circle>
<circle class="progress" r="40" cx="50" cy="50" fill="none"></circle>
</g>
</svg>

I surmise from your question that you must be reducing the circle radius. Am I correct?
If you reduce the circle radius the circumference of the circle reduces as well. The "251" value, in the stroke-dashoffset property, corresponds to the circumference.
circumference = 2*PI*r = 2*PI*40 ~= 251
The animation works by shifting the position of a line dash pattern, so that it appears to slowly draw the line.
If you halve the radius, the circumference will halve as well. If you don't also correct the stroke-dashoffset, the animation will appear to complete in half the time. That's because the animation has already reached the new circumference of 126 after 5 seconds.
To fix this, just update the stroke-dashoffset value to 126.
If you want to use a radius other than 20, you'll need to work out the correct circumference/stroke-dashoffset for that also.
.progress-circle.definite .progress {
stroke: orange;
stroke-width: 2;
stroke-dashoffset: 0;
stroke-dasharray: 126;
animation: progress-anim 10s ease;
}
.progress-circle.definite .bg {
stroke: white;
stroke-width: 2;
}
#keyframes progress-anim {
0% { stroke-dashoffset: 126; }
100% { stroke-dashoffset: 0; }
}
// indefinite
<svg class="progress-circle definite" width="100" height="100">
<defs>
<linearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="transparent"/>
<stop offset="100%" stop-color="black"/>
</linearGradient>
</defs>
<g transform="rotate(-90,50,50)">
<circle class="bg" r="20" cx="50" cy="50" fill="url(#linear)"></circle>
<circle class="progress" r="20" cx="50" cy="50" fill="none"></circle>
</g>
</svg>

Related

SVG animation is not applied properly when a shape is moved

I'm trying to apply SVG animation to a triangle which is moved by (100, 100) pixels:
<svg width="800" height="600">
<polyline shapeId="triangle" fill="transparent" stroke="gray" points="0,0 52.5,160 105,0 0,0 " transform=" translate(100 100)">
</polyline>
</svg>
I was expecting the triangle to be rotating around point (100, 100). However, the triangle is rotating around the origin of the SVG document:
<svg width="800" height="600">
<polyline shapeId="triangle" fill="transparent" stroke="gray" points="0,0 52.5,160 105,0 0,0 " transform=" translate(100 100)">
<animateTransform attributeName="transform" type="rotate" begin="0s" dur="5s" repeatCount="indefinite" from="0" to="360"/>
</polyline>
</svg>
If I specify rotation offset in the animation tag, the results are still not what I would expect: the triangle does not rotate around one of its corners.
<svg width="800" height="600">
<polyline shapeId="triangle" fill="transparent" stroke="gray" points="0,0 52.5,160 105,0 0,0 " transform=" translate(100 100)">
<animateTransform attributeName="transform" type="rotate" begin="0s" dur="5s" repeatCount="indefinite" from="0 100 100" to="360 100 100"/>
</polyline>
</svg>
What I want to achieve is triangle rotating around one of its cornered while moved by (100, 100) pixels.
How can I achieve this? Thank you.
You could always transform a parent element...
<svg width="800" height="600">
<g transform="translate(100 100)">
<polyline shapeId="triangle" fill="transparent" stroke="gray" points="0,0 52.5,160 105,0 0,0 " >
<animateTransform attributeName="transform" type="rotate" begin="0s" dur="5s" repeatCount="indefinite" from="0" to="360"/>
</polyline>
</g>
</svg>

SVG animate a bezier curve to grow by following an arrowhead

I'm trying to create an arrow with its arrowhead moving from a starting point and ending at its target. Moving the arrowhead was achieved successfully with the tip from #Robert Longson. I want the end of the shaft also to follow the arrowhead and grow to its full length. The code is given below and notice that the shaft isn't growing with the arrowhead and also ends up in partial length. Is there a way to correct this. Any help will be greatly appreciated.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="5 0 100 45">
<style>
.wire {
fill: none;
stroke: red;
stroke-width: 1px;
/* Stroke-dasharray property to animate */
stroke-dasharray: 100%;
stroke-dashoffset: 100%;
animation: move linear 5s;
}
#keyframes move {
100% {
stroke-dashoffset: 0;
}
}
</style>
<path d="M10,10 C15,50 95,50 100,10" stroke="blue" stroke-width="2" id="wire" class="wire">
<animate>
<mpath xlink:href="#wire" />
</animate>
</path>
<!-- acceptable movement along the path but incorrect orientation -->
<polygon points="-5,-5 5,0 -5,5 -3,0" fill="red">
<animateMotion dur="5s" repeatCount="1" rotate="auto" fill="freeze">
<mpath xlink:href="#wire" />
</animateMotion>
</polygon>
</svg>
Like this I guess. Note that you could have done this in SMIL too.
I've set the animation to be forwards so it remains at the end, otherwise the curve disappears at the end of the animation.
The console.log line shows you where I got the number from.
console.log(document.getElementsByTagName("path")[0].getTotalLength())
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="5 0 100 45">
<style>
.wire {
fill: none;
stroke: red;
stroke-width: 1px;
/* Stroke-dasharray property to animate */
stroke-dasharray: 118.27912902832031;
stroke-dashoffset: 118.27912902832031;
animation: move linear 5s forwards;
}
#keyframes move {
100% {
stroke-dashoffset: 0;
}
}
</style>
<path d="M10,10 C15,50 95,50 100,10" stroke="blue" stroke-width="2" id="wire" class="wire">
<animate>
<mpath xlink:href="#wire" />
</animate>
</path>
<!-- acceptable movement along the path but incorrect orientation -->
<polygon points="-5,-5 5,0 -5,5 -3,0" fill="red">
<animateMotion dur="5s" repeatCount="1" rotate="auto" fill="freeze">
<mpath xlink:href="#wire" />
</animateMotion>
</polygon>
</svg>
To move the cursor and line at the same time:
It is necessary to synchronize both animations in start time begin="svg1.click" and duration dur="5s"
The maximum curve length is 118.3px so
stroke-dashoffset:118.3px;
stroke-dasharray:118.3px;
#wire {
stroke-dashoffset:118.3px;
stroke-dasharray:118.3px;
stroke:red;
stroke-width:2px;
fill:none;
}
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="5 0 100 45">
<style>
</style>
<path id="wire" d="M10,10 C15,50 95,50 100,10" >
<!-- Curved path growth animation -->
<animate
attributeName="stroke-dashoffset"
begin="svg1.click"
dur="5s"
values="118.3;0"
calcMode="linear"
fill="freeze"
restart="whenNotActive" />
</animate>
</path>
<!-- Cursor -->
<polygon points="-5,-5 5,0 -5,5 -3,0" fill="red">
<!-- Animating cursor movement along a curved path -->
<animateMotion begin="svg1.click" dur="5s" repeatCount="1" calcMode="linear" rotate="auto" fill="freeze">
<mpath xlink:href="#wire" />
</animateMotion>
</polygon>
<text x="40" y="20" font-size="6px" fill="dodgerblue">Click me</text>
</svg>
<script>
var path = document.querySelector('#wire');
var len = (path.getTotalLength() );
console.log("Path length - " + len);
</script>
UPDATE
as a bonus:
Moving forward - backward
To control the direction of movement, add two buttons and an
onclick event
<div>
<button onclick="forward.beginElement()">forward</button>
<button onclick="back.beginElement()">back</button>
</div>
The direction of the cursor is controlled by a couple of arguments:
keyPoints="0;1"
keyTimes="0;1"
Animation of line growing or falling depends on the value of
stroke-dashoffset
values="118.3;0" - line growth
values="0;118.3" - decrease line`
#wire {
stroke-dashoffset:118.3px;
stroke-dasharray:118.3px;
stroke:red;
stroke-width:2px;
fill:none;
}
svg {
width:50%;
height:50%;
}
<div>
<button onclick="forward.beginElement()">forward</button>
<button onclick="back.beginElement()">back</button>
</div>
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="5 0 100 45">
<style>
</style>
<path id="wire" d="M10,10 C15,50 95,50 100,10" >
<!-- Animation of filling, growing a line (`forward`)-->
<animate id="strokeForward"
attributeName="stroke-dashoffset"
begin="forward.begin"
dur="5s"
values="118.3;0"
calcMode="linear"
fill="freeze"
restart="whenNotActive" />
<!-- String decrease animation (`back`) -->
<animate id="strokeBack"
attributeName="stroke-dashoffset"
begin="back.begin"
dur="5s"
values="0;118.3"
calcMode="linear"
fill="freeze"
restart="whenNotActive" />
</path>
<!-- Cursor -->
<polygon points="-5,-5 5,0 -5,5 -3,0" fill="red">
<!-- Animating cursor movement along a curved path (`forward`) -->
<animateMotion
id="forward"
begin="indefinite"
dur="5s"
repeatCount="1"
calcMode="linear"
rotate="auto"
fill="freeze"
keyPoints="0;1"
keyTimes="0;1"
restart="whenNotActive">
<mpath xlink:href="#wire" />
</animateMotion>
<!-- Animating cursor movement along a curved path (`back`) -->
<animateMotion
id="back"
begin="indefinite"
dur="5s"
repeatCount="1"
calcMode="linear"
rotate="auto"
fill="freeze"
keyPoints="1;0"
keyTimes="0;1"
restart="whenNotActive">
<mpath xlink:href="#wire" />
</animateMotion>
</polygon>
</svg>

SVG animate gradient along path

I have the following svg that i would like to animate. I would like the red part moves along the path up to the end (so from the top right side to the left bottom side) :
The problem is : obviously is quite impossible to have a gradient following a path. Here is my code so far :
<svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362">
<defs>
<style>
.cls-3{
fill: none;
stroke-miterlimit:10;
stroke-width:3px;
}
</style>
<linearGradient id="light" x1="100%" y1="100%">
<stop offset="70%" stop-color="#3E3E3E">
<!-- <animate attributeName="stop-color" to="#CF4B59" from="#3E3E3E" dur="0.5s" fill="freeze" /> -->
</stop>
<stop offset="100%" stop-color="#CF4B59">
<!-- <animate attributeName="stop-color" from="#CF4B59" to="#3E3E3E" dur="0.5s" fill="freeze" /> -->
</stop>
</linearGradient>
</defs>
<g id="Calque_2" data-name="Calque 2">
<g id="Calque_1-2" data-name="Calque 1">
<g class="cls-2">
<path class="cls-3" id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" transform="translate(-52.32 -8.93)" stroke="url(#light)"/>
</g>
</g>
</g>
</svg>
I tried to use "animate" to make it move along the path, but it's a vertical gradient which is applied and goes from the top to the bottom and not a gradient which follows the path.
I had other ideas to overcome this :
Maybe by using a second path which would be the same shape than the first one but with inverted gradient so I could make it slide along the initial path maybe
Or, I could use opacity to make the final path appear but i'm not sure i will be able to make the red part move in this way...
If you have some ideas to make the red part move from the top right to the bottom left it would help me a lot!
Question
I would like the red part moves along the path up to the end (so from
the top right side to the left bottom side) :
Consider using fill-line animation with stroke-dashoffset.
For clarity, I placed exactly the same curve below which will show the route of filling the line with color
If this indication of the motion path is not necessary, simply remove the path id = "trace"
<svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362">
<defs>
<style>
.cls-3{
fill: none;
stroke-miterlimit:10;
stroke-width:3px;
stroke:#E7E7E7;
}
#base {
fill: none;
stroke:crimson;
stroke-width:3px;
stroke-dashoffset:1732;
stroke-dasharray:1732;
animation: fillStroke 10s linear forwards;
}
#keyframes fillStroke {
to {stroke-dashoffset:0;}
}
</style>
</defs>
<g transform="translate(-352.32 -8.93)">
<path id="trace" class="cls-3" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" />
<g class="cls-2">
<path id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" >
</path>
</g>
</g>
</svg>
Gradient animation option
Instead of filling with color as the length of the curve increases, a gradient will perform this function
<svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362">
<defs>
<style>
.cls-3{
fill: none;
stroke-miterlimit:10;
stroke-width:3px;
stroke:#E7E7E7;
}
#base {
fill: none;
stroke:url(#light);
stroke-width:3px;
stroke-dashoffset:1732;
stroke-dasharray:1732;
animation: fillStroke 10s linear forwards;
}
#keyframes fillStroke {
to {stroke-dashoffset:0;}
}
</style>
<linearGradient id="light" x1="100%" y1="100%">
<stop offset="50%" stop-color="#CF4B59">
<!-- <animate attributeName="stop-color" from="#CF4B59" to="#3E3E3E" dur="10s" fill="freeze" /> -->
</stop>
<stop offset="100%" stop-color="#3E3E3E">
<!-- <animate attributeName="stop-color" to="#CF4B59" from="#3E3E3E" dur="10s" fill="freeze" /> -->
</stop>
</linearGradient>
</defs>
<g transform="translate(-352.32 -8.93)">
<path class="cls-3" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" />
<g class="cls-2">
<path id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" >
</path>
</g>
</g>
</svg>

SMIL animation doesn't work on a use element on Firefox

Although this animation is working on Chrome, Safary and Opera, it doesn't work on Firefox when I'm using the group:
svg {
max-width: 90vh;
stroke-linecap: round;
display:block;
position:absolute;
margin:auto;
top:0;bottom:0;left:0;right:0;
}
path {
stroke: black;
stroke-width: 0.2;
fill: none;
}
circle {
fill: black;
}
<svg id="svg" viewBox="-50 -50 100 100">
<g id="slice">
<path d="M8.390747629378028, 4.0407710911278985Q16.337096335644915,1.578047643071413 28.72564510652592,5.067456639486153Q41.114193877406926,8.556865635900893 22.230907302700192,4.260374440788638Q3.3476207279934576,-0.03611675432361651 21.46226478304126,-6.962030472005244Q39.57690883808906,-13.887944189686872 31.396381359458864,-2.1315394650039874Q23.215853880828664,9.624865259678897 22.336451060888443,2.1742972246208847Q21.457048240948225, -5.276270810437127, 8.390747629378028, -4.0407710911278985" id="theCurve"></path>
<circle r="1">
<animateMotion begin="0s" dur="10s" repeatCount="indefinite">
<mpath xlink:href="#theCurve"></mpath>
</animateMotion>
</circle>
</g>
<use xlink:href="#slice" transform="rotate(200)"></use>
</svg>
This was fixed very recently. You can use a Nightly in the meantime or just wait till September's release of Firefox 69.
In order to make it work I'm putting the used path and the animated circle in a group and I'm rotating the group:
svg {
border:1px solid;
max-width: 90vh;
stroke-linecap: round;
display:block;
position:absolute;
margin:auto;
top:0;bottom:0;left:0;right:0;
}
path {
stroke: black;
stroke-width: 0.2;
fill: none;
}
circle {
fill: black;
}
<svg id="svg" viewBox="-50 -50 100 100">
<defs>
<path d="M8.390747629378028, 4.0407710911278985Q16.337096335644915,1.578047643071413 28.72564510652592,5.067456639486153Q41.114193877406926,8.556865635900893 22.230907302700192,4.260374440788638Q3.3476207279934576,-0.03611675432361651 21.46226478304126,-6.962030472005244Q39.57690883808906,-13.887944189686872 31.396381359458864,-2.1315394650039874Q23.215853880828664,9.624865259678897 22.336451060888443,2.1742972246208847Q21.457048240948225, -5.276270810437127, 8.390747629378028, -4.0407710911278985" id="theCurve"></path>
</defs>
<g transform="rotate(0)">
<use xlink:href="#theCurve" ></use>
<circle r="1">
<animateMotion begin="0s" dur="10s" repeatCount="indefinite">
<mpath xlink:href="#theCurve"></mpath>
</animateMotion>
</circle>
</g>
<g transform="rotate(200)">
<use xlink:href="#theCurve" ></use>
<circle r="1">
<animateMotion begin="0s" dur="10s" repeatCount="indefinite">
<mpath xlink:href="#theCurve"></mpath>
</animateMotion>
</circle>
</g>
</svg>

How to make an object rotate around the exact center of the screen using animateTransform?

Consider the following SVG code for moving a circle around the center of the screen, with hard-coded dimensions:
<svg xmlns="http://www.w3.org/2000/svg">
<g>
<ellipse id="circ" style="fill:#000000"
cx="60%" cy="50%"
rx="10" ry="10" />
<!--Assuming window size is 1000x1000-->
<animateTransform attributeName="transform"
type="rotate" dur="10s"
from="0,500,500"
to="360,500,500"
repeatCount="indefinite"/>
</g>
</svg>
If I try to provide the center of rotation in percent, the animation doesn't work at all:
<animateTransform attributeName="transform"
type="rotate" dur="10s"
from="0,50%,50%"
to="360,50%,50%"
repeatCount="indefinite"/>
How do I fix this?
Set a viewBox on your SVG, then whatever size you make it, the ellipse will rotate around the centre of it.
viewBox="0 0 1000 1000"
The value of 1000 for width and height here is chosen because it would make 500 be the centre.
svg:nth-child(1) {
width: 200px;
}
svg:nth-child(2) {
width: 500px;
}
svg {
border: solid 1px green;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
<g>
<ellipse id="circ" style="fill:#000000"
cx="60%" cy="50%"
rx="10" ry="10" />
<!--Assuming window size is 1000x1000-->
<animateTransform attributeName="transform"
type="rotate" dur="10s"
from="0,500,500"
to="360,500,500"
repeatCount="indefinite"/>
</g>
</svg>
<!-- An exact duplicate of th first one -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
<g>
<ellipse id="circ" style="fill:#000000"
cx="60%" cy="50%"
rx="10" ry="10" />
<!--Assuming window size is 1000x1000-->
<animateTransform attributeName="transform"
type="rotate" dur="10s"
from="0,500,500"
to="360,500,500"
repeatCount="indefinite"/>
</g>
</svg>

Resources