为什么我的 SVG 动画循环会跳过某些部分?
Why is my SVG animation loop skipping some parts?
我正在开发一个小的 svg 组件,它可以生成如下代码片段中的图表。
我想为它制作动画。现在,我只是尝试制作类似呼吸的效果,但线条动画无法正确循环。我将它分成两部分,并使用 animateTransform
技巧在另一部分执行时暂停其中一部分。它适用于第一次迭代,但不适用于第二次和其余迭代。
对于可能遇到此主题的 SVG Jedi,请告诉我是否应该更改一些动画属性以使其更加 smooth/performant。这是多次试验和错误的产物,我不是该领域的专家。
相关部分在这里
<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>
这是一个完整的代码片段版本(如果您知道如何折叠代码,请编辑)
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.
因为你的动画很复杂。我没有费心去调试它。我只是用更简单的形式重写了它。
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>
我正在开发一个小的 svg 组件,它可以生成如下代码片段中的图表。
我想为它制作动画。现在,我只是尝试制作类似呼吸的效果,但线条动画无法正确循环。我将它分成两部分,并使用 animateTransform
技巧在另一部分执行时暂停其中一部分。它适用于第一次迭代,但不适用于第二次和其余迭代。
对于可能遇到此主题的 SVG Jedi,请告诉我是否应该更改一些动画属性以使其更加 smooth/performant。这是多次试验和错误的产物,我不是该领域的专家。
相关部分在这里
<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>
这是一个完整的代码片段版本(如果您知道如何折叠代码,请编辑)
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.
因为你的动画很复杂。我没有费心去调试它。我只是用更简单的形式重写了它。
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>