svg动画详解

259 阅读3分钟

这篇文章的目的并不是让大家对svg动画有什么深刻的认识,因为对于前端开发来说使用css动画还是比较习惯的,并且css动画可以控制svg的属性,具体的实践过程中完全可以使用css动画替换svg动画。这篇文章只是方便大家查阅svg动画,在用到svg动画的时候能看懂代码,能够修改。
先来一个简单的例子:

    <rect x="10" y="10" width="200" height="20" stroke="black" fill="none"> 
        <animate attributeName="width" attributeType="XML" from="200" to="20" begin="0s" dur="5s" fill="freeze" />
    </rect>
    

从字面意思很好理解:
attributeName:要改变的属性
attributeType:可以取两个值XML/CSS,默认css,XML指的是属性值,这个例子中width是rect的一个属性
from:动画起始值,可以不传默认是当前值
to:动画结束时的值
fill:动画结束时的状态,可以取freeze(保持结束时状态)/remove(回到最初状态),默认remove
begin:开始时间
dur:动画持续时间
repeatCount:动画重复次数,取整数
repeatDur:这个是在某个时间段内重复,如果同时定义了repeatCount,按照早结束的算
repeatCount/repeatDur赋值infdefinite,就可以使动画无限重复。

上面一个animate元素只能有一个值,如果想要同时改变矩形高度和宽度,就需要另外加一个动画,代码如下:

    <rect x="10" y="10" width="200" height="20" stroke="black" fill="none"> 
        <animate attributeName="width" attributeType="XML" from="200" repeatCount="3"  to="20" begin="0s" dur="5s" fill="freeze" />
        <animate attributeName="height" attributeType="XML" from="20" repeatCount="indefinite"  to="50" begin="0s" dur="5s"/>
    </rect>
    

同步动画

svg中有个有意思的动画属性,beigin:可以取其他动画的结束时间、重复时间、开始时间并且可以做时间加减,例如:begin:otherAnimate.end。这样就可以让多个元素进行动画同步,例如:

<rect x="10" y="10" width="200" height="20" stroke="black" fill="none"> 
    <animate attributeName="width" id="ani1" attributeType="XML" from="200" to="20" begin="0s" dur="5s" fill="freeze" />
</rect>

<rect x="10" y="10" width="200" height="20" stroke="black" fill="none"> 
    <animate attributeName="height" attributeType="XML" from="20" repeatCount="indefinite"  to="50" begin="ani1.end" dur="5s"/>
</rect>

这样可以在一个动画结束的时候控制另外一个动画开始。对于一组连续的动画非常有用。除了and外还可以使用如下:begin=ani1.repeat(1)+ 1s等。

复杂属性变化

这个要单独说一下,这个可以说是svg对于css相对优势的地方,例如将三角形变为五边形。效果如下:

tring.gif

代码如下:

<svg width="500" height="500" viewBox="0 0 500 500">
    <polygon points="150 20 200 120 250 220 50 220 100 120" fill="none" stroke="black" stroke-width="2">
        <animate keyTimes="0; 0.2; 1" attributeName="points" values="150 20 200 120 250 220 50 220 100 120;150 20 250 100 250 220 50 220 50 100;150 20 200 120 250 220 50 220 100 120;" begin="0s" dur="2s" repeatCount="100"></animate>
    </polygon>
</svg>

可以看到使用values属性可以指定动画的多个值,使用keyTimes可以控制多个值之间的时间间隔,这里面注意点数必须是相同的,有兴趣的同学可以试试点数不同的效果。

animateTransform元素

animate并不使用元素的平移,旋转,缩放,倾斜变换,对于这样的变换需要用专门的元素animateTransform,

    <rect x="10" y="20" width="20" height="20" style="fill: #ff9; stroke: black;"> 
        <animateTransform attributeType="XML" attributeName="transform" 
        type="scale" from="1" to="2" begin="0s" dur="4s" fill="freeze"/> 
    </rect>

属性值和animate是一样的,不再重复介绍。

animateMotion元素

该动画主要是让元素沿着某条路径移动。例如如下例子:

motion.gif

代码如下:

<path d="M10,110 A120,120 -45 0,1 110 10 A120,120 -45 0,1 10,110" stroke="lightgrey" stroke-width="2" 
fill="none" id="theMotionPath"/> 
<circle cx="10" cy="110" r="3" fill="lightgrey" /> 
<circle cx="110" cy="10" r="3" fill="lightgrey" /> 
<circle cx="" cy="" r="5" fill="red"> 
    <animateMotion dur="6s" repeatCount="indefinite"> 
        <mpath xlink:href="#theMotionPath"/> 
    </animateMotion> 
</circle>

结束语

和css比起来现在svg动画优势不大了,这些动画效果都可以用css实现,路径动画可以使用css的offset-path,只有图像变化css实现起来不太方便,所以在实际项目中的动画效果,除非是图形本身形状变换我们要使用svg动画,其他的都可以使用css实现。