【问题标题】:SVG reversing animationSVG倒车动画
【发布时间】:2017-06-27 16:43:48
【问题描述】:

我仍在学习 SMIL,而困扰我的一件事是不支持自动反转动画。所以这是我的测试 SVG 我制作了 quicky flor 的目的是测试 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>

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

我知道这个问题已经被问过几次了,例如Here。他们似乎都只使用keyPointskeyTimes 覆盖&lt;motionPath&gt; 元素,如果有办法使用我的SVG 使用运动路径来实现这一点也很好,我只是不确定如何。

提前感谢您的帮助!

【问题讨论】:

    标签: css animation svg smil


    【解决方案1】:

    是的,您与keyTimes 合作顺利。
    但是您的&lt;animate&gt; 需要的是values 属性。

    基本上,对于每个&lt;animate&gt;,我

    • 添加了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>

    如果你想要我做的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');
    })
    <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>

    【讨论】:

    • 哇,谢谢!也很好解释。请问你是用什么程序把fromto移到values的?
    • 看起来您需要像这样 keyTimes="0;0.5;1" 删除 keyTimes 中的空格才能使其在 Safari 中工作(至少在 Safari 9.1.3 中)
    • @eye-wonder 谢谢!我一直怀疑哪个浏览器支持哪种语法……所以我遵循了 MDN 的。坏主意 ;-) 但是 safari 10 没问题。
    猜你喜欢
    • 2019-08-27
    • 2014-05-17
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多