SVG倒车动画

Vic*_*und 0 css animation svg smil

我仍在学习 SMIL,让我烦恼的一件事是不支持自动反转动画。所以这是我的测试 SVG 我快速创建了测试 SVG 位置动画的目的。

以最简单的形式,我希望动画在到达终点时反转回其原始起始位置,就像 CSS 动画的alternate工作方式一样。

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124 82">
  <defs>
    <style>
      .cls-1 {
        fill: none;
        stroke: #000;
        stroke-miterlimit: 10;
        stroke-width: 2px;
      }
    </style>
  </defs>
  <title>Untitled-5</title>
  <line class="cls-1" x1="12" y1="70" x2="44" y2="12">
    <animate class="anim_1" attributeName="y1" from="70" to="35" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="x2" from="44" to="59" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="y2" from="12" to="56" dur="2s" repeatCount="indefinite"/>
  </line>
  <line class="cls-1" x1="44" y1="12" x2="112" y2="45">
    <animate class="anim_1" attributeName="x1" from="44" to="59" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="y1" from="12" to="56" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="x2" from="112" to="100" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="y2" from="45" to="12" dur="2s" repeatCount="indefinite"/>
  </line>
  <circle cx="12" cy="70" r="11" fill="white" stroke="black" stroke-width="2">
    <animate class="anim_1" attributeName="cy" from="70" to="35" dur="2s" repeatCount="indefinite"/>
  </circle>
  <circle cx="44" cy="12" r="11" fill="white" stroke="black" stroke-width="2">
    <animate class="anim_1" attributeName="cx" from="44" to="59" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="cy" from="12" to="56" dur="2s" repeatCount="indefinite"/>
  </circle>
  <circle cx="112" cy="45" r="11" fill="white" stroke="black" stroke-width="2">
    <animate class="anim_1" attributeName="cx" from="112" to="100" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="cy" from="45" to="12" dur="2s" repeatCount="indefinite"/>
  </circle>
</svg>
Run Code Online (Sandbox Code Playgroud)

如您所见,动画完美运行,直到到达结尾,然后直接跳回到开头。不幸的是,我实现较大 SVG 的方式不支持 JS 更改<svg>元素。

我知道这个问题已经被问过几次了,例如这里。它们似乎都只<motionPath>使用keyPointsand覆盖元素keyTimes,如果有一种方法可以使用我的 SVG 使用运动路径来实现这一点,那也很好,我只是不确定如何。

预先感谢您的帮助!

Kai*_*ido 5

是的,您在使用keyTimes.
但是你需要的<animate>values属性。

基本上,对于每个<animate>,我

  • 添加keyTimes = "0; .5; 1"以便我们获得 3 个航点
  • 转换fromto属性为values="from;to;from"
  • 更改了dur使其长两倍。

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124 82">
  <defs>
    <style>
      .cls-1 {
        fill: none;
        stroke: #000;
        stroke-miterlimit: 10;
        stroke-width: 2px;
      }
    </style>
  </defs>
  <title>Untitled-5</title>
  <line class="cls-1" x1="12" y1="70" x2="44" y2="12">
    <animate class="anim_1" attributeName="y1" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="70;35;70"></animate>
    <animate class="anim_1" attributeName="x2" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="44;59;44"></animate>
    <animate class="anim_1" attributeName="y2" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="12;56;12"></animate>
  </line>
  <line class="cls-1" x1="44" y1="12" x2="112" y2="45">
    <animate class="anim_1" attributeName="x1" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="44;59;44"></animate>
    <animate class="anim_1" attributeName="y1" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="12;56;12"></animate>
    <animate class="anim_1" attributeName="x2" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="112;100;112"></animate>
    <animate class="anim_1" attributeName="y2" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="45;12;45"></animate>
  </line>
  <circle cx="12" cy="70" r="11" fill="white" stroke="black" stroke-width="2">
    <animate class="anim_1" attributeName="cy" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="70;35;70"></animate>
  </circle>
  <circle cx="44" cy="12" r="11" fill="white" stroke="black" stroke-width="2">
    <animate class="anim_1" attributeName="cx" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="44;59;44"></animate>
    <animate class="anim_1" attributeName="cy" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="12;56;12"></animate>
  </circle>
  <circle cx="112" cy="45" r="11" fill="white" stroke="black" stroke-width="2">
    <animate class="anim_1" attributeName="cx" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="112;100;112"></animate>
    <animate class="anim_1" attributeName="cy" dur="4s" repeatCount="indefinite" keyTimes="0;0.5;1" values="45;12;45"></animate>
  </circle>
</svg>
Run Code Online (Sandbox Code Playgroud)

如果你想要我做的js:

document.querySelectorAll('animate').forEach(a => {
  a.setAttribute('keyTimes', '0;0.5;1');
  let f = a.getAttribute('from');
  let t = a.getAttribute('to');
  a.setAttribute('values', f + ';' + t + ';' + f)
  a.removeAttribute('from');
  a.removeAttribute('to');
  a.setAttribute('dur', (parseFloat(a.getAttribute('dur')) * 2) + 's');
})
Run Code Online (Sandbox Code Playgroud)
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124 82">
  <defs>
    <style>
      .cls-1 {
        fill: none;
        stroke: #000;
        stroke-miterlimit: 10;
        stroke-width: 2px;
      }
    </style>
  </defs>
  <title>Untitled-5</title>
  <line class="cls-1" x1="12" y1="70" x2="44" y2="12">
    <animate class="anim_1" attributeName="y1" from="70" to="35" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="x2" from="44" to="59" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="y2" from="12" to="56" dur="2s" repeatCount="indefinite"/>
  </line>
  <line class="cls-1" x1="44" y1="12" x2="112" y2="45">
    <animate class="anim_1" attributeName="x1" from="44" to="59" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="y1" from="12" to="56" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="x2" from="112" to="100" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="y2" from="45" to="12" dur="2s" repeatCount="indefinite"/>
  </line>
  <circle cx="12" cy="70" r="11" fill="white" stroke="black" stroke-width="2">
    <animate class="anim_1" attributeName="cy" from="70" to="35" dur="2s" repeatCount="indefinite"/>
  </circle>
  <circle cx="44" cy="12" r="11" fill="white" stroke="black" stroke-width="2">
    <animate class="anim_1" attributeName="cx" from="44" to="59" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="cy" from="12" to="56" dur="2s" repeatCount="indefinite"/>
  </circle>
  <circle cx="112" cy="45" r="11" fill="white" stroke="black" stroke-width="2">
    <animate class="anim_1" attributeName="cx" from="112" to="100" dur="2s" repeatCount="indefinite"/>
    <animate class="anim_1" attributeName="cy" from="45" to="12" dur="2s" repeatCount="indefinite"/>
  </circle>
</svg>
Run Code Online (Sandbox Code Playgroud)