Reputation: 630
I'd like to add a delay to each iteration of an SVG animation loop. Here's a simple example.
<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
<circle cx="50" cy="50" r="15" fill="blue">
<animate id="op" attributeType="CSS" attributeName="opacity"
from="1" to="0" dur="3s" repeatCount="indefinite" />
</circle>
</svg>
Using begin
only delays the first iteration, so, is there a way to delay every iteration?
Upvotes: 16
Views: 32989
Reputation: 24482
If you want your animation to alternate (similar to what animation-direction: alternate;
does in CSS), and you want to have a different delay for the initial/start/first repetition vs subsequent repetitions, here I provide two workarounds. See this GitHub issue in SVG Working Group repo.
<circle fill="#f5ca20" r="5" cx="12" cy="12">
<animate id="anim1" attributeName="r" dur="1s" fill="freeze" begin="3s; anim2.end + 5s" to="10" keyTimes="0; 1" calcMode="spline" keySplines="0.37, 0, 0.63, 1"/>
<animate id="anim2" attributeName="r" dur="1s" fill="freeze" begin="anim1.end + 5s" to="5" keyTimes="0; 1" calcMode="spline" keySplines="0.37, 0, 0.63, 1"/>
</circle>
values
and keyTimes
attributes<circle fill="#f5ca20" r="5" cx="12" cy="12">
<animate attributeName="r" dur="12s" begin="3s" values="5; 10; 10; 5; 5" keyTimes="0; 0.083; 0.5; 0.583; 1" repeatDur="indefinite" calcMode="spline" keySplines="0.37, 0, 0.63, 1; 0, 0, 1, 1; 0.37, 0, 0.63, 1; 0, 0, 1, 1"/>
</circle>
In this approach you should calculate the total duration of animations plus delays and assign it to dur
and also calculate the keyTimes
values for your durations. For my example, the total duration is 12s
and the times 3s 🡲 1s 🡲 5s 🡲 1s 🡲 5s maps to keyTimes="0; 0.083; 0.5; 0.583; 1"
.
calcMode="..."
and keySplines="..."
are optional (they specify timing interpolation)Both of the above produce the following result:
Upvotes: 1
Reputation: 173
Here's a more elaborated version of Danjiro Daiwa's example without the hidden rectangle to synchronise the animation and without resorting to setting the orange circles out of the visible area to hide them, using opacity="0"
instead. There are four animation running at the same time, a1/a2 for the movement, o1/o2 to hide the orange doppelganger circles when they're moving behind/over the blue circle, r1-r4 to change the radius r
and f1-f4 to change fill
colour.
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="200px">
<circle fill="#f70" cx="0" cy="100" r="20" opacity="0">
<animate id="a1" attributeName="cx" begin="0s;a2.end" from="250" to="50" dur="3s"/>
<animate id="o1" attributeName="opacity" begin="a1.begin" end="a1.end" from="1" to="1"/>
<animate id="r1" attributeName="r" begin="a1.begin" from="20" to="15" dur="1.5s"/>
<animate id="r2" attributeName="r" begin="r1.end" from="15" to="20" dur="1.5s"/>
<animate id="f1" attributeName="fill" begin="a1.begin" from="#f70" to="#c00" dur="1.5s"/>
<animate id="f2" attributeName="fill" begin="f1.end" from="#c00" to="#f70" dur="1.5s"/>
</circle>
<circle fill="blue" cx="150" cy="100" r="50" />
<circle fill="#f90" cx="0" cy="100" r="20" opacity="0">
<animate id="a2" attributeName="cx" begin="a1.end" from="50" to="250" dur="2s"/>
<animate id="o2" attributeName="opacity" begin="a2.begin" end="a2.end" from="1" to="1"/>
<animate id="r3" attributeName="r" begin="a2.begin" from="20" to="25" dur="1s"/>
<animate id="r4" attributeName="r" begin="r3.end" from="25" to="20" dur="1s"/>
<animate id="f3" attributeName="fill" begin="a2.begin" from="#f70" to="#ff0" dur="1s"/>
<animate id="f4" attributeName="fill" begin="f3.end" from="#ff0" to="#f70" dur="1s"/>
</circle>
</svg>
Upvotes: 0
Reputation: 61
Below an example of "closing eyes"... thanks to the suggestions in this thread.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 16"><g>
<g >
<ellipse cx="9.45" cy="7.7" rx="0.96" ry="0.96" style="stroke: none; fill: black;">
<animate id="op" attributeName="ry" attributeType="XML"
to="0.1"
begin="3s;op.end+3s" dur="0.15s"
fill="remove" repeatCount="2"
/>
</ellipse>
<ellipse cx="14.6" cy="7.8" rx="0.8" ry="0.8" style="stroke: none; fill: black;">
<animate id="op" attributeName="ry" attributeType="XML"
to="0.1"
begin="3s;op.end+3s" dur="0.15s"
fill="remove" repeatCount="2"
/>
</ellipse>
</g>
</svg>
Upvotes: 3
Reputation: 51
Define dummy loop and set relative start time. See How to make SVG Loop Animation?
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="200px">
<rect>
<animate id="o1" begin="0;o1.end" dur="10s"
attributeName="visibility" from="hide" to="hide"/>
</rect>
<circle fill="orange" cx="-50" cy="100" r="20">
<animate begin="o1.begin"
attributeName="cx" from="250" to="50" dur="5.05s"/>
</circle>
<circle fill="blue" cx="150" cy="100" r="50" />
<circle fill="orange" cx="-50" cy="100" r="20">
<animate begin="o1.begin+5s"
attributeName="cx" from="50" to="250" dur="5.05s"/>
</circle>
</svg>
Upvotes: 4
Reputation: 28553
I think what you're looking for is the additive/accumulative attributes of the svg. This is an example that i got from css tricks
svg {
border: 3px solid #eee;
display: block;
margin: 1em auto;
}
<svg width="500" height="100">
<circle id="orange-circle" r="30" cx="50" cy="50" fill="orange" />
<animate xlink:href="#orange-circle" attributeName="cx" from="0" to="100" additive="sum" repeatCount="3" calcMode="spline" keyTimes="0;1" keySplines=".42 0 1 1" dur="1s" begin="click" fill="freeze" />
</svg>
In fact here is a better exaample (same source)
svg {
border: 3px solid #eee;
display: block;
margin: 1em auto;
}
<svg width="500" height="150">
<style>
rect {
-moz-transform-origin: 75px 75px;
transform-origin: 50% 50%;
}
</style>
<rect id="deepPink-rectangle" width="50" height="50" x="50" y="50" fill="deepPink" />
<animateTransform
xlink:href="#deepPink-rectangle"
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 75 75"
to="360 75 75"
dur="2s"
begin="0s; 5s; 9s; 17s;"
end="2s; 8s; 15s; 25s;"
fill="freeze"
restart="whenNotActive"
/>
</svg>
Upvotes: 0
Reputation: 136638
You can add the end
event of a SMIL animated element to the begin
attribute.
Also, you can add multiple values, separated by ;
to this begin
attribute :
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="100px">
<circle cx="50" cy="50" r="15" fill="blue">
<animate id="op" attributeType="CSS" attributeName="opacity"
from="1" to="0" dur="3s" begin="3s;op.end+3s" />
</circle>
</svg>
Upvotes: 42