I am working with this following and trying SMIL animation
for the first time.
If you take a look, you would realize that the animation is not smooth, there is a jump at the end.
How can I make this to run smoothly without any jump?
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
<defs>
<filter id="trip">
<feTurbulence id="turbulence" baseFrequency="10" numOctaves="20" seed="10" stitchTiles="stitch">
<animate id="noiseAnimate" attributeName="baseFrequency" attributeType="XML" from="10" to="15" begin="0s" dur="5s" repeatCount="indefinite"></animate>
</feTurbulence>
<feDisplacementMap in="SourceGraphic" scale="1"></feDisplacementMap>
</filter>
</defs>
<rect id="bg" width="200" height="200" fill="black">
</rect>
<rect id="bg" x="50" y="50" width="30" height="30" fill="white" filter="url(#trip)">
</rect>
</svg>
CodePudding user response:
Let's ignore the question whether your animation is a good choice, and just look at the syntax involved.
<animate ... from="10" to="15" repeatCount="indefinite"></animate>
The behavior of this animation is just the same as the CSS property animation-direction: normal
:
[E]ach time the animation cycles, the animation will reset to the beginning state and start over again.
After moving from 10 to 15, it jumps back to 10 and starts over.
While CSS has a value of animation-direction: alternate
to describe an animation that moves smoothly forth and back, the same does not exist for SMIL. Instead, you have to describe a movement that has three values: the start value, the end value, and the start value again. This cannot be described with the from
and to
attributes, but with values
.
Additionally, you have to set the keyTimes
attribute. In an interval of 0...1 it describes when, relative to the simple duration, the value is reached.
<animate ... values="10;15;10" keyTimes="0;.5;1" repeatCount="indefinite"></animate>
Note: For animating baseFrequency
, you have to set stitchTiles="noStitch"
, as otherwise the frequency is changed in such discrete steps that the Perlin cell size is always an integral fraction of the primitive filter region size.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
<defs>
<filter id="trip">
<feTurbulence id="turbulence" baseFrequency="10" numOctaves="20"
seed="10" stitchTiles="noStitch">
<animate id="noiseAnimate" attributeName="baseFrequency" attributeType="XML"
values="10;15;10" keyTimes="0;.5;1" begin="0s" dur="5s"
repeatCount="indefinite"></animate>
</feTurbulence>
<feDisplacementMap in="SourceGraphic" scale="1"></feDisplacementMap>
</filter>
</defs>
<rect id="bg" width="200" height="200" fill="black">
</rect>
<rect id="bg" x="50" y="50" width="30" height="30" fill="white" filter="url(#trip)">
</rect>
</svg>