使用 animate 标签为转换(旋转)的 SVG 组设置动画
Posted
技术标签:
【中文标题】使用 animate 标签为转换(旋转)的 SVG 组设置动画【英文标题】:Animate a transformed (rotated) SVG group with animate tag 【发布时间】:2021-06-07 11:29:34 【问题描述】:我想要为已转换(旋转)的 SVG 组制作动画。为此,我插入了动画标签。在我的示例中,我正在为垂直线元素设置动画,因此动画标签插入到结束线标签之前。如果线没有被旋转,这将非常有效。但是,旋转线后,整个上下文都旋转了,我的动画指令也旋转了。我希望线条从顶部开始动画,向下到画布的中间,然后回到顶部。然而,在旋转之后,它从右侧进来并从右侧出去,因为整个上下文已被旋转(我的示例代码如下)。我尝试在结束组元素之前插入 animate 标记,并且还尝试了 animateTransform 标记。结束组标记之前的动画标记没有做任何事情,并且 animateTransform 标记给了我运动,但是线又是水平的,在错误的位置,并且它不尊重我的 keySplines 值(缓动)。我需要一些方法来保持我的元素转换,但能够根据用户的说明从上/右/下/左动画进/出。
我需要一个内联的 SVG 解决方案(而不是 CSS)。该应用程序是一个视频幻灯片编辑器,可导出此代码块,该代码块在以 html/SVG 编写的播放器上呈现。我的幻灯片编辑器使用 Fabric JS 编辑和导出 SVG 元素。
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 992 558" xml:space="preserve" preserveAspectRatio="none" style="position:absolute; width:100%; left:0; background-color: null" id="svg">
<desc>Created with Fabric.js 3.6.3</desc>
<defs></defs>
<g transform="matrix(0 0.68 -1 0 455.92 235.39)">
<line style="stroke: rgb(0,0,0); stroke-width: 4; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; visibility: hidden;" vector-effect="non-scaling-stroke" x1="-175" y1="0" x2="175" y2="0" layerId="1">
<animate attributeName="y1" attributeType="XML" begin="0.7441050156739812s" dur="1.25s" values="-1000; 0" repeatCount="1" fill="freeze" calcMode="spline" keySplines="0.14 0.22 0.12 0.99" />
<set attributeName="visibility" from="hidden" to="visible" begin="0.7441050156739812s" />
<animate attributeName="y2" attributeType="XML" begin="0.7441050156739812s" dur="1.25s" values="-1000; 0" repeatCount="1" fill="freeze" calcMode="spline" keySplines="0.14 0.22 0.12 0.99" />
<set attributeName="visibility" from="hidden" to="visible" begin="0.7441050156739812s" />
<animate attributeName="y1" attributeType="XML" begin="2.132496081504702s" dur="1.25s" values="0; -1000" repeatCount="1" fill="freeze" calcMode="spline" keySplines="0.7 0 0.53 0.99" />
<set attributeName="visibility" from="visible" to="hidden" begin="4.132496081504701s" />
<animate attributeName="y2" attributeType="XML" begin="2.132496081504702s" dur="1.25s" values="0; -1000" repeatCount="1" fill="freeze" calcMode="spline" keySplines="0.7 0 0.53 0.99" />
<set attributeName="visibility" from="visible" to="hidden" begin="4.132496081504701s" />
</line>
</g>
</svg>
【问题讨论】:
您的用例是否可以通过更改x
和 y
属性来以这种方式旋转线条,或者该组内是否有更多(和不同)元素?
如果运行代码sn -p,可以看到线是垂直的。这就是意图。我想要它做的是保持垂直,但从顶部滑入,然后从画布上滑回顶部。现在它从右边滑入/滑出,因为包括动画标签在内的整个组都已被转换。
【参考方案1】:
我很确定我上面的评论被误解了,所以我使用我想到的技术提供了一个基本的答案。
不是旋转整个组,而是做一条垂直线,而是摆脱组上的旋转,而是以这种方式设置x1
,x2
和y1
和y2
坐标,你得到一条垂直线。这样您就可以轻松地应用动画,而无需旋转任何东西。基本思想概述如下:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 992 558" xml:space="preserve" preserveAspectRatio="none" style="position:absolute; width:100%; left:0; background-color: null" id="svg">
<desc>Created with Fabric.js 3.6.3</desc>
<defs></defs>
<g>
<line style="stroke: rgb(0,0,0); stroke-width: 4; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; visibility: hidden;" vector-effect="non-scaling-stroke" x1="10" y1="-175" x2="10" y2="175" layerId="1">
<animate attributeName="y1" attributeType="XML" begin="0.7441050156739812s" dur="1.25s" values="0; 500" repeatCount="1" fill="freeze" calcMode="spline" keySplines="0.14 0.22 0.12 0.99" />
<set attributeName="visibility" from="hidden" to="visible" begin="0.7441050156739812s" />
<animate attributeName="y2" attributeType="XML" begin="0.7441050156739812s" dur="1.25s" values="-350; 150" repeatCount="1" fill="freeze" calcMode="spline" keySplines="0.14 0.22 0.12 0.99" />
<set attributeName="visibility" from="hidden" to="visible" begin="0.7441050156739812s" />
</line>
</g>
</svg>
但是,您也可以在为属性设置动画时仅考虑旋转(因此,然后为 x1
和 x2
属性设置动画,而不是 y1
和 y2
):
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 992 558" xml:space="preserve" preserveAspectRatio="none" style="position:absolute; width:100%; left:0; background-color: null" id="svg">
<desc>Created with Fabric.js 3.6.3</desc>
<defs></defs>
<g transform="matrix(0 0.68 -1 0 455.92 235.39)">
<line style="stroke: rgb(0,0,0); stroke-width: 4; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; visibility: hidden;" vector-effect="non-scaling-stroke" x1="-175" y1="0" x2="175" y2="0" layerId="1">
<animate attributeName="x1" attributeType="XML" begin="0.7441050156739812s" dur="1.25s" values="-1000; 0" repeatCount="1" fill="freeze" calcMode="spline" keySplines="0.14 0.22 0.12 0.99" />
<set attributeName="visibility" from="hidden" to="visible" begin="0.7441050156739812s" />
<animate attributeName="x2" attributeType="XML" begin="0.7441050156739812s" dur="1.25s" values="-650; 350" repeatCount="1" fill="freeze" calcMode="spline" keySplines="0.14 0.22 0.12 0.99" />
<set attributeName="visibility" from="hidden" to="visible" begin="0.7441050156739812s" />
<animate attributeName="x1" attributeType="XML" begin="2.132496081504702s" dur="1.25s" values="0; -1000" repeatCount="1" fill="freeze" calcMode="spline" keySplines="0.7 0 0.53 0.99" />
<set attributeName="visibility" from="visible" to="hidden" begin="4.132496081504701s" />
<animate attributeName="x2" attributeType="XML" begin="2.132496081504702s" dur="1.25s" values="350; -650" repeatCount="1" fill="freeze" calcMode="spline" keySplines="0.7 0 0.53 0.99" />
<set attributeName="visibility" from="visible" to="hidden" begin="4.132496081504701s" />
</line>
</g>
</svg>
还请记住,x1
和 x2
必须保持相同的距离(在您发布的代码中是 350
)。
【讨论】:
以上是关于使用 animate 标签为转换(旋转)的 SVG 组设置动画的主要内容,如果未能解决你的问题,请参考以下文章
Adobe Animate Snap SVG 插件 - 巨大的文件