如何使用animate标签对svg路径的d属性进行动画处理

4

我正在尝试使用animate标签对svg path进行动画处理,参考自css tricks的这篇教程。我可以使用css关键帧来动画化路径,结果如下:

#mySvg path{    
    animation: scale-path 10s ease-in-out infinite;
}

@keyframes scale-path {
    50% {
        d: path('M1036,540L883,540L883,693Z');
    }
}
<svg id="mySvg" xmlns:svg="http://www.w3.org/2000/svg" 
     xmlns="http://www.w3.org/2000/svg" 
     version="1.1" 
     x="0"
     y="0"
     width="100%"
     height="100%" 
     viewBox="0 0 1920 1080" 
     preserveAspectRatio="none">
      
     <path d="M1045,520L1173,558L1184,393Z"   
              fill="lightblue" 
              stroke="#eee9ea" 
              stroke-width="1.51" />
</svg>

但问题是我无法使用animate标签实现相同的动画效果(将会有很多带有不同动画的path标签)。我不确定这是否是正确的语法:

<svg id="mySvg" xmlns:svg="http://www.w3.org/2000/svg" 
     xmlns="http://www.w3.org/2000/svg" 
     version="1.1" 
     x="0"
     y="0"
     width="100%"
     height="100%" 
     viewBox="0 0 1920 1080" 
     preserveAspectRatio="none">
      
    <path d="M1045,520L1173,558L1184,393Z" 
          fill="lightblue" 
          stroke="#eee9ea" 
          stroke-width="1.51">
          
            <animate 
            attributeName="d"
            from="M1045, 520L1173, 558L1184, 393Z"
            to="M1036; 540L883; 540L883; 693Z" 
            dur="10s"
            repeatCount="indefinite"
            values="M1036; 540L883; 540L883; 693Z"
            keyTimes="0.5;" />
     </path>
</svg>

2个回答

6
您正在错误地编写值,应注意使用;。路径的整个值使用,作为分隔符(例如:M1045, 520L1173, 558L1184, 393Z),这些值在values属性内部由;分隔。

<svg id="mySvg" xmlns:svg="http://www.w3.org/2000/svg" 
     xmlns="http://www.w3.org/2000/svg" 
     version="1.1" 
     x="0"
     y="0"
     width="100%"
     height="100%" 
     viewBox="0 0 1920 1080" 
     preserveAspectRatio="none">
      
    <path d="M1045,520L1173,558L1184,393Z" 
          fill="lightblue" 
          stroke="#eee9ea" 
          stroke-width="1.51">
          
            <animate 
            attributeName="d"
            from="M1045, 520L1173, 558L1184, 393Z"
            to="M1036, 540L883, 540L883, 693Z" 
            dur="5s"
            values="M1045, 520L1173, 558L1184, 393Z;M1036, 540L883, 540L883, 693Z;M1045, 520L1173, 558L1184, 393Z"
            repeatCount="indefinite" />
     </path>
</svg>


这些由分号 ; 分隔的 values 表示 0%、50% 和 100% 吗? - SilverSurfer
@SilverSurfer 不,我的意思是这是d的值 --> M1045, 520L1173, 558L1184, 393Z,你可以有不同的值,像这样用;分隔,就像在values属性中一样。 - Temani Afif
那么在动画属性中没有 keyframes % 这个东西? - SilverSurfer
@SilverSurfer 不是的,它的等效方法是在值属性中定义您想要进行转换的不同值。因此,动画将从第一个值开始平稳地结束到最后一个值。 - Temani Afif
Temani的答案是不正确的。 “这些由;分隔的值表示0%,50%和100%?” 是的,没错。 “所以在动画属性中不存在关键帧百分比?” 是的,您可以使用keyTimes来实现。但是,如果您的关键帧在时间“0”和时间“1”之间均匀分布,则无需使用keyTimes指定时间。 - Paul LeBeau
@PaulLeBeau 啊,那我当时没理解他的意思,我以为他在谈论他最初编写的代码%。 - Temani Afif

6
分号(;)用于属性中的分隔符,如valueskeyTimes,以标记不同的关键帧值。这两个属性中的值的数量应该匹配。
您似乎已经用分号替换了逗号,这是不正确的。
如果您正在两个值之间进行动画处理(A -> B),则只需要使用fromto。如果您需要在三个或更多值之间进行动画处理,则需要使用valueskeyTimes
SMIL动画中没有自动的来回循环。因此,如果您尝试从A到B再返回到A,则需要使用valueskeyTimes,并以"A; B; A"的形式列出您的值。
像这样:

<svg id="mySvg" xmlns:svg="http://www.w3.org/2000/svg" 
     xmlns="http://www.w3.org/2000/svg" 
     version="1.1" 
     x="0"
     y="0"
     width="100%"
     height="100%" 
     viewBox="0 0 1920 1080" 
     preserveAspectRatio="none">
      
    <path d="M 1045,520 L 1173,558 L 1184,393 Z" 
          fill="lightblue" 
          stroke="#eee9ea" 
          stroke-width="1.51">
          
            <animate 
            attributeName="d"
            dur="10s"
            repeatCount="indefinite"
            values="M 1045,520 L 1173,558 L 1184,393 Z;
                    M 1036,540 L 883,540 L 883,693 Z;
                    M 1045,520 L 1173,558 L 1184,393 Z"
            keyTimes="0; 0.5; 1" />
     </path>
</svg>

如果你的动画是线性进行的,并且keyTimes的时间是均匀分布的,就像这里一样,实际上你不需要提供keyTimes


希望他能回来接受你的答案.. 我仍然需要更准确的SVG :p - Temani Afif
你的回答很好。OP不需要改变他们的投票。我只是决定回答,因为我认为需要更多的解释。 - Paul LeBeau
是的,你说得对,我完全误解了他的评论,他可能也是这样...另外,我省略了keyTimes部分,因为我认为他们对他来说不是必要的,但看起来他需要它们来控制%。 - Temani Afif
谢谢你们的答案,非常有帮助。 - SilverSurfer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接