【问题标题】:Why is my SVG animation loop skipping some parts?为什么我的 SVG 动画循环会跳过某些部分?
【发布时间】:2022-01-05 10:27:31
【问题描述】:

我正在开发一个小 svg 组件,它可以生成如下面的 sn-p 中的图形。

我想为它制作动画。现在,我只是尝试制作类似呼吸的效果,但线条动画无法正确循环。我将它分成两部分,并使用animateTransform 技巧在另一部分执行时暂停其中一部分。它适用于第一次迭代,但不适用于第二次和其余部分。

对于可能遇到此主题的 SVG Jedi,请告诉我是否应该更改某些动画属性以使其更流畅/性能更好。这是多次试验和错误的产物,我不是该领域的专家。

相关部分在这里


    <line :x1="ox" :y1="oy" :stroke="isHeading ? 'white' : '#FFFFF0'">
      <animateTransform
        id="pause"
        begin="expandAnim.end"
        dur="3s"
        type="translate"
        attributeType="XML"
        attributeName="transform"
        repeatCount="indefinite"
      />
      <animateTransform
        id="pause2"
        begin="pause.end"
        dur="3s"
        type="translate"
        attributeType="XML"
        attributeName="transform"
        repeatCount="indefinite"
      />
      <animate
        id="expandAnim"
        attributeName="x2"
        :from="cx"
        :to="dx"
        dur="3s"
        begin="0; pause.end"
        repeatCount="indefinite"
      />
      <animate
        fill="freeze"
        attributeName="y2"
        :from="cy"
        :to="dy"
        dur="3s"
        begin="0; pause.end"
        repeatCount="indefinite"
      />
      <animate
        id="collapseAnim"
        attributeName="x2"
        fill="freeze"
        :from="dx"
        :to="cx"
        dur="3s"
        begin="3; expandAnim.end"
        repeatCount="indefinite"
      />
      <animate
        attributeName="y2"
        fill="freeze"
        :from="dy"
        :to="cy"
        dur="3s"
        begin="3; expandAnim.end"
        repeatCount="indefinite"
      />
    </line>

这是一个完整的sn-p版本(如果你知道如何折叠代码,请编辑)

svg {
  background-color:black
}
.is-hl {
  fill: white;
  stroke: white;
}
.heading-placeholder {
  fill: transparent;
  stroke: white;
}
circle {
  fill: transparent;
  stroke: white;
}
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" class="article-fingerprint d-flex">
  <rect id="overlay" width="100%" height="100%" fill="url(#g1)"></rect>
  <g transform="translate(125, 125)">
    <circle fill="url(#bgGradient)" cx="0" cy="0" r="64.66666666666667"></circle>
    <g class="type-element" idx="0">
      <line x1="3.959691317243109e-15" y1="-64.66666666666667" stroke="#FFFFF0">
        <animateTransform id="pause" begin="expandAnim.end" dur="3s" type="translate" attributeType="XML" attributeName="transform" repeatCount="indefinite"></animateTransform>
        <animateTransform id="pause2" begin="pause.end" dur="3s" type="translate" attributeType="XML" attributeName="transform" repeatCount="indefinite"></animateTransform>
        <animate id="expandAnim" attributeName="x2" from="5.5460389524011505e-15" to="6.158362351974827e-15" dur="3s" begin="0; pause.end" repeatCount="indefinite"></animate>
        <animate fill="freeze" attributeName="y2" from="-90.57368959380808" to="-100.57368959380808" dur="3s" begin="0; pause.end" repeatCount="indefinite"></animate>
        <animate id="collapseAnim" attributeName="x2" fill="freeze" from="6.158362351974827e-15" to="5.5460389524011505e-15" dur="3s" begin="3; expandAnim.end" repeatCount="indefinite"></animate>
        <animate attributeName="y2" fill="freeze" from="-100.57368959380808" to="-90.57368959380808" dur="3s" begin="3; expandAnim.end" repeatCount="indefinite"></animate>
      </line>
      <circle cx="3.959691317243109e-15" cy="-64.66666666666667" r="1" class="origin"></circle>
      <!---->
      <!---->
      <path id="circlePath24336" d="M5.5460389524011505e-15,-90.57368959380808 L6.158362351974827e-15,-100.57368959380808 L5.5460389524011505e-15,-90.57368959380808" fill="none"></path>
      <circle r="2.590702292714141">
        <animateMotion dur="6s" repeatCount="indefinite" fill="freeze">
          <mpath xlink:href="#circlePath24336"></mpath>
        </animateMotion>
      </circle>
    </g>
  </g>
</svg>

作为一个附带问题,由于我还没有深入研究它的性能方面,所以继续制作这个动画看起来是一种明智的方式吗?还是坚持以中心为原点的 CSS 缩放动画会更好?

还有一个问题:在悬停时触发此动画是否可行?我没有花太多时间在上面,但由于动画小线条和圆圈位于用于触发的叠加层的子组件中,我不确定如何传播 SVG 事件,例如overlay.mouseover 给它。请注意,我使用的是 vue。

【问题讨论】:

  • 一个可能的原因是您有重复的id 属性。例如:pauseexpandAnimcollapseAnimids 需要在文档中是唯一的。
  • 其实可以排除动画错误的原因。我将您的代码简化为一组动画,它仍然会发生。重复的ids 仍然是一个错误。

标签: css animation svg graph smil


【解决方案1】:

因为你的动画很复杂。我没有费心去调试它。我只是用更简单的形式重写了它。

svg {
  background-color:black
}
.is-hl {
  fill: white;
  stroke: white;
}
.heading-placeholder {
  fill: transparent;
  stroke: white;
}
circle {
  fill: transparent;
  stroke: white;
}
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" class="article-fingerprint d-flex">
  <rect id="overlay" width="100%" height="100%" fill="url(#g1)"></rect>
  <g transform="translate(125, 125)">
    <circle fill="url(#bgGradient)" cx="0" cy="0" r="64.66666666666667"></circle>
    <g class="type-element" idx="0">
      <line x1="3.959691317243109e-15" y1="-64.66666666666667" stroke="#FFFFF0">
        <animate attributeName="x2"
                 dur="6s" repeatCount="indefinite"
                 values="0; 0; 0"
                 keyTimes="0; 0.5; 1"/>
        <animate attributeName="y2"
                 dur="6s" repeatCount="indefinite"
                 values="-90.573; -100.573; -90.573"
                 keyTimes="0; 0.5; 1"/>
      </line>
      <circle r="2.590702292714141">
        <animateTransform attributeName="transform"
                 type="translate"
                 dur="6s" repeatCount="indefinite"
                 values="0,-90.573; 0,-100.573; 0,-90.573"
                 keyTimes="0; 0.5; 1"/>
      </circle>
    </g>
  </g>
</svg>

【讨论】:

  • 嗯,首先,谢谢@Paul!我需要详细查看它以了解您的操作方式。您能否也让我知道以这种方式进行而不是 CSS 缩放动画是否是个好主意?再次感谢!
  • 您可以将其转换为使用 CSS 动画。但请注意,动画几何相关属性(例如 x2y2)是相对较新的事情,可能不适用于使用某些浏览器或某些旧浏览器版本的人。
猜你喜欢
  • 2021-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-07
  • 1970-01-01
  • 2020-05-19
  • 1970-01-01
  • 2014-07-06
相关资源
最近更新 更多