31.SVG动画

有多种不同的方法可以为SVG图片中的图形添加动画。在本文中,我将介绍各种可能的动画。

SVG动画示例

下面是一个简单的SVG动画例子:

<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">

    <rect x="10" y="10" height="110" width="110"
         style="stroke:#ff0000; fill: #0000ff">

        <animateTransform
            attributeName="transform"
            begin="0s"
            dur="20s"
            type="rotate"
            from="0 60 60"
            to="360 60 60"
            repeatCount="indefinite"
        />
    </rect>

</svg>

请注意,在<rect>元素内嵌套了一个<animateTransform>元素。正是这个元素为矩形添加了动画。

最终的SVG动画如下:

动画选项概述

动画就是根据时间的推移操作图形的属性。通过下面5个SVG动画元素中的一个或多个可以实现。

每一个SVG动画元素都为SVG图形的不同方面添加设置或动画。本文的后续部分将对这些动画元素作详细描述。

set

set是SVG动画中最简单的元素。它只是在特定时间间隔过去后将属性设置为某个值。因此,形状的动画不是连续的,而是只改变属性值一次。

下面是一个<set>元素例子:

<circle cx="30" cy="30" r="25" style="stroke: none; fill: #0000ff;">
    <set attributeName="r" attributeType="XML"
         to="100"
         begin="5s"  />

</circle>

可以发现,<set>元素嵌套在circle元素内。这就是<set>元素应用到图形的方法——将其嵌套在SVG图形内部。

<set>元素在特定时间设置属性的值,要设置的属性的名称在attributeName属性中指定。在to属性中指定将为其设置的值,设置属性值的时间在begin属性中指定。

上面的例子在5秒后将属性r设置为100,最终图片如下:

attributeType

上述例子的<set>元素中还有一个值为XMLattributeType属性。这是因为在示例中设置值的属性(r属性)是SVG circle元素的属性。由于SVG元素是XML元素,因此SVG属性是XML属性。

你也可以为形状的CSS属性设置动画,如果想这么做,你需要将attributeType设置为CSS。如果你未提供attributeType属性,那么浏览器将尝试猜测添加动画的属性是XML属性还是CSS属性。

animate

animate元素用来为SVG形状的属性添加动画。你可以将animate元素嵌套在形状内。示例如下:

<circle cx="30" cy="30" r="25" style="stroke: none; fill: #0000ff;">
    <animate attributeName="cx" attributeType="XML"
             from="30"  to="470"
             begin="0s" dur="5s"
             fill="remove" repeatCount="indefinite"/>

</circle>

这个例子中,将<circle>元素的cx属性从30(from属性)变到了470(to属性)。动画从0秒(begin属性)开始,持续5秒(dur属性)。

当动画结束时,动画属性被设置为原始值(fill="remove"设置)。如果你希望动画结束时动画属性保持最终的值不变,可以将fill属性设置为freeze。动画无限重复(repeatCount属性)。

最终的动画如下:

animateTransform

<animateTransform>元素可以为形状的transform属性设置动画,而<animate>元素不能这么做。

示例如下:

<rect x="20" y="20" width="100" height="40"
    style="stroke: #ff00ff; fill:none;" >
  <animateTransform attributeName="transform"
                    type="rotate"
                    from="0 100 100" to="360 100 100"
                    begin="0s" dur="10s"
                    repeatCount="indefinite"
          />
</rect>

<animateTransform>例子为其外部<rect>元素的transform属性添加动画。其type属性被设置为rotate(旋转变换函数),表示动画变换将是一个旋转。fromto属性被设置为动画需要的参数并传递给rotate函数。该示例围绕点100,100从0度旋转到360度。

下面是一个为正方形添加放大动画的示例:

<rect x="20" y="20" width="40" height="40"
      style="stroke: #ff00ff; fill: none;" >
    <animateTransform attributeName="transform"
                      type="scale"
                      from="1 1" to="2 3"
                      begin="0s" dur="10s"
                      repeatCount="indefinite"
            />
</rect>

再次注意,fromto属性包含的值作为参数传递给scale()变换函数。

最终的动画如下:

animateMotion

<animateMotion>元素可以使形状沿着路径的线路移动。它也可以旋转形状以匹配路径的坡度,就像一辆上下行驶的汽车。示例代码如下:

<rect x="0" y="0" width="30" height="15"
      style="stroke: #ff0000; fill: none;">
    <animateMotion
            path="M10,50 q60,50 100,0 q60,-50 100,0"
            begin="0s" dur="10s" repeatCount="indefinite"
            />
</rect>

<animateMotion>元素的path属性中指定用于对矩形进行动画处理的路径。path属性和path元素使用相同的语法。

下面动画中的路径是为了更好的显示运动路径。

为了旋转正方形以与路径的斜率对齐,请将<animateMotion>元素的rotate属性设置为auto。示例如下:

<rect x="0" y="0" width="30" height="15"
      style="stroke: #ff0000; fill: none;">
    <animateMotion
            path="M10,50 q60,50 100,0 q60,-50 100,0"
            begin="0s" dur="10s" repeatCount="indefinite"
            rotate="auto"
            />
</rect>

最终动画如下,注意方向的旋转如何改变以适应路径。

你也可以将rotate属性设置为特定的值,例如20或30等。这将保持形状旋转动画中的度数。

时间单位

当你定义一个SVG动画时,需要指定动画的开始和持续时间。你可以选择不同的时间单位指定它们的值。时间单位通常在各种动画元素的begindurend属性内指定。

在这些属性中,你可以指定一个数字后面带一个时间单位,如本文示例中所做。例如5s表示5秒。下面是一个你可以使用的时间单位的列表:

时间单位

描述

h

小时

min

分钟

s

ms

毫秒

你也可以包含小时、分钟和秒的时间格式指定时间。格式如下:

hh:mm:ss

示例如下:

1:30:45

此示例指定一个小时,30分钟和45秒的时间(当然,对于动画来说这是非常长的)。

协调动画

你可以同步一个动画的开头到另一个动画的结尾,像下面这样做:

<rect x="0" y="0" width="30" height="15"
      style="stroke: #ff0000; fill: none;">

    <animate id="one"
             attributeName="x" attributeType="XML"
             from="0" to="400"
             begin="0s" dur="10s" fill="freeze"
            />
    <animate
            attributeName="y" attributeType="XML"
            from="0" to="50"
            begin="one.end" dur="10s" fill="freeze"
            />
</rect>

最终动画如下:

第一个动画的id属性为one

第二个动画引用通过其begin属性引用第一个动画。begin属性值设置为one.end,这意味着当id为one的动画结束时,该动画开始。

你可以使用id.beginid.end在另一个动画开始或结束时启动动画。使用要同步的动画元素的ID属性替代这里的id

你也可以像下面这样,为另一个动画的开始和结束时间指定偏移:

one.begin+10s
one.end+5s

此外,你可以在动画的end属性中显示指定结束时间,这不会替换dur属性。所以无论先发生什么,它所做的就是为动画添加另一个可能的结束。示例如下:

<animate
        attributeName="y" attributeType="XML"
        from="0" to="50"
        begin="one.begin+3s" dur="10s" end="one.end"
        fill="freeze"
        />

这个动画的持续时间为10秒,或者当ID为one的动画结束时停止(以先发生的动画为准)。

重复动画

动画元素上有两个属性可以用来实现重复效果的动画。

第一个属性是repeatCount,你可以为其设置一个数值,动画会重复固定数值的次数,如果将其设置为indefinite,动画会一直保持。

第二个属性是repeatDur,其指定动画重复的持续事件。你也可以将其设置为indefinite,其效果和repeatCount一样。

请看下面两个例子:

<animate
        attributeName="y" attributeType="XML"
        from="0" to="50"
        begin="one.begin+3s" dur="10s"
        repeatCount="3"
        fill="freeze"
        />
<animate
        attributeName="y" attributeType="XML"
        from="0" to="50"
        begin="one.begin+3s" dur="10s"
        repeatDur="30s"
        fill="freeze"
        />

组合动画

你可以通过在元素中添加多个<animate>来组合动画。你之前已经看到过,但这里是另一个例子:

<rect x="10" y="10" width="40" height="20"
     style="stroke: #000000; fill: none;">
   <animate attributeName="x"
            attributeType="XML"
            from="10" to="400"
            begin="0s" dur="10s"
            repeatCount="indefinite"
           />
   <animate attributeName="y"
            attributeType="XML"
            from="10" to="100"
            begin="0s" dur="10s"
            fill="freeze"
            repeatCount="indefinite"
           />
</rect>

这个例子有两个动画,分别为长方形的xy属性添加动画。最终动画如下:

当组合<animateTransform>元素时,默认行为是第二个动画取消第一个动画。但是,你可以通过向两个<animateTransform>元素添加值为sumadditive属性实现转换动画的组合。示例如下:

<rect x="10" y="10" width="40" height="20"
      style="stroke: #000000; fill: none;">
    <animateTransform attributeName="transform" attributeType="XML"
                      type="scale"
                      from="1" to="3"
                      begin="0s" dur="10s"
                      repeatCount="indefinite"
                      additive="sum"
            />
    <animateTransform attributeName="transform" attributeType="XML"
                      type="rotate"
                      from="0 30 20" to="360 30 20"
                      begin="0s" dur="10s"
                      fill="freeze"
                      repeatCount="indefinite"
                      additive="sum"
            />

最终动画如下,同时缩放和旋转矩形:

最后更新于