如何完美循环 feTurbulence 动画

How to perfectly loop feTurbulence animation

我正在使用以下内容并第一次尝试 SMIL animation

如果你看一下,你会发现动画不流畅,最后有一个跳跃。

我怎样才能顺利地运行不跳转?

<svg class="layer1" 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 class="bg" id="bg" width="200" height="200" fill="black">
</rect>
<rect class="bg" id="bg" x="50" y="50" width="30" height="30" fill="white" filter="url(#trip)">
</rect>
</svg>

让我们忽略你的动画是否是一个好的选择这个问题,只看涉及的语法。

<animate ... from="10" to="15" repeatCount="indefinite"></animate>

此动画的行为与 CSS property animation-direction: normal:

[E]ach time the animation cycles, the animation will reset to the beginning state and start over again.

从 10 移动到 15 后,它跳回到 10 并重新开始。

虽然 CSS 的值是 animation-direction: alternate 来描述平滑前后移动的动画,但 SMIL 不存在同样的值。相反,您必须描述具有三个值的移动:开始值、结束值和再次开始值。这不能用 fromto 属性来描述,而是用 values.

此外,您还必须设置 keyTimes 属性。在 0...1 的间隔中,它描述了相对于简单持续时间何时达到该值。

<animate ... values="10;15;10" keyTimes="0;.5;1" repeatCount="indefinite"></animate>

注意:要设置 baseFrequency 动画,您必须设置 stitchTiles="noStitch",否则频率会以不连续的步长变化,以至于 Perlin cell size 始终是原始滤波器区域大小的整数部分。

<svg class="layer1" 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 class="bg" id="bg" width="200" height="200" fill="black">
</rect>
<rect class="bg" id="bg" x="50" y="50" width="30" height="30" fill="white" filter="url(#trip)">
</rect>
</svg>