How can I make an SVG animation repeat ?
-
hmm ... I can't upload an SVG, because the allowed image types don't include it
Anyway, I wrote a nice little animation as an SVG, that runs nicely through a single 18s cycle of everything I wanted to do, then I addedrepeatDur="18s" restart="always" repeatCount="indefinite"
to the attributes of each set element
I imagined this line would cause each animation to restart its clock 18s after the image loaded and replay its events, so that my little animation would play out continuously.
However, what it actually does appears to be: change dur to 18s, fill to "freeze".The animation does not repeat. Elements no longer disappear once their allotted dur has expired (as they did before I added the repeat-controls) but persist for what I suspect is 18s each (it's hard to be sure, as they also end up overlapping other things that appear where they shouldn't have remained). Then all of them finally remove themselves, one by one (seemingly in the order they appeared, to the extent the same overlap issue lets me tell), leaving all animated parts gone.
Here's a simpler illustration: traffic lights, left column without repeat, right column with (and the repeatDur changed to 6s):
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="10em" class="etartsulli" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <g stroke="none" visibility="hidden"> <circle cx="25" cy="19" r="12" fill="green"> <set attributeName="visibility" attributeType="CSS" to="visible" begin="0s" dur="2s" fill="remove" /> </circle> <circle cx="25" cy="50" r="12" fill="orange"> <set attributeName="visibility" attributeType="CSS" to="visible" begin="2s" dur="2s" fill="remove" /> </circle> <circle cx="25" cy="81" r="12" fill="red"> <set attributeName="visibility" attributeType="CSS" to="visible" begin="4s" dur="2s" fill="remove" /> </circle> <circle cx="75" cy="19" r="12" fill="green"> <set attributeName="visibility" attributeType="CSS" to="visible" repeatDur="6s" restart="always" repeatCount="indefinite" begin="0s" dur="2s" fill="remove" /> </circle> <circle cx="75" cy="50" r="12" fill="orange"> <set attributeName="visibility" attributeType="CSS" to="visible" repeatDur="6s" restart="always" repeatCount="indefinite" begin="2s" dur="2s" fill="remove" /> </circle> <circle cx="75" cy="81" r="12" fill="red"> <set attributeName="visibility" attributeType="CSS" to="visible" repeatDur="6s" restart="always" repeatCount="indefinite" begin="4s" dur="2s" fill="remove" /> </circle> </g> </svg>
The left lights each show for two seconds, in turn.
The right lights each show for six seconds, overlapping.The same is true in Chromium.
Either I've wildly misunderstood what these repeat and restart properties do, or this is a bug in Chrome's SVG animation code. -
PPathduck moved this topic from Forum on
-
hmm ... so it seems repeatDur isn't the duration of one repeat cycle, it's how long to keep repeating the animation for - which, for an attribute setting, amounts to overriding its duration after all. Apparently I need to set begin="0s;18s;36s;..." although I'd rather have a way to set "and every 18s after that". It seemed like begin="0s;+18s" is a valid begin value, but it didn't do what I expected, i.e. begin again every 18s later.
-
... and it turns out the trick is to give one of the set elements an id, I picked the one for the green light to come on and called it go; then begin="0s;go.begin+6s" makes it repeat and the others can be given begin="go.begin+2s" and similar for 4s, to make working traffic lights:
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="10em" class="etartsulli" viewBox="0 0 30 100" xmlns="http://www.w3.org/2000/svg"> <g stroke="none" visibility="hidden"> <circle cx="15" cy="19" r="12" fill="green"> <set attributeName="visibility" attributeType="CSS" to="visible" id="go" begin="0s;go.begin+6s" dur="2s" fill="remove" /> </circle> <circle cx="15" cy="50" r="12" fill="orange"> <set attributeName="visibility" attributeType="CSS" to="visible" begin="go.begin+2s" dur="2s" fill="remove" /> </circle> <circle cx="15" cy="81" r="12" fill="red"> <set attributeName="visibility" attributeType="CSS" to="visible" begin="go.begin+4s" dur="2s" fill="remove" /> </circle> </g> </svg>
So all just my failure to make sense of the SVG spec - problem solved ;^>