Press "Enter" to skip to content

SVG 中的平滑动画

HTML5 中对于 SVG 的引入极大的丰富了 Web 页面的表现力,而且,SVG 本身就支持动画。通过使用 <animate/> 或者 <animateTransform/> 元素可以让 SVG 元素产生动画,还有更加高端的 <animateMotion/> 可以产生沿着路径移动的动画。

但是在实际的使用中发现,SVG 的动画帧率比较低,甚至存在直观上能够感受到的卡顿现象,尤其是在移动设备上查看的时候。如何能够让 SVG 的动画也达到丝般顺滑的效果?

如果您的 SVG 动画只是改变元素的位置、大小、旋转等,那么可以将需要动画展示的 SVG 元素封装到一个 DIV 元素中,然后使用 CSS3 动画,让 DIV 元素产生动画,那么可以收获相当平滑的效果。因为 SVG 元素动画还是要重新计算元素的数据信息,而使用 CSS3 对 SVG 的容器 DIV 元素进行动画是不需要重新计算 SVG 的数据的,所以效果要好很多。

点击查看动画实例

先看一下,直接使用 <animateTransform/> 元素和使用 DIV 容器 + CSS3 动画的帧率对比:

使用 animateTransform 元素 使用 DIV 容器 + CSS3 动画
animate-transform css3-transform

可以看出来,使用 <animateTransform/> 产生的 SVG 动画,帧率大概在 30 FPS 左右,而使用 DIV 容器 + CSS3 动画,帧率可以达到 60 FPS 左右,很明显这两种方式还是有很大的直观感受的区别的。

附录代码:

直接使用 <animateTransform/> 的代码如下:

<svg id="s2" xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink"
     width="344" height="344" style="width: 344px; height: 344px; border: 1px solid green;">
    <g id="g2">
        <animateTransform
        attributeName="transform"
                      attributeType="XML"
                      type="translate"
                      from="0 0"
                      to="300 300"
                      dur="2s"
                      repeatCount="5"
        />
        <path fill="none" stroke="red" d="M0,0 L10,10 c50,0 50,100 100,100 50,0 50,-100 100,-100 l60,60" z='100'/>
    </g>
</svg>

使用 DIV 容器 + CSS3 动画的代码如下:

动画样式:

div#d1 {
    -webkit-animation-name: moveme;
    -webkit-animation-duration: 2s;
    -webkit-animation-timing-function: linear;
    -webkit-animation-iteration-count: 5;

}
@-webkit-keyframes moveme {
    0% {
        -webkit-transform: translate(0, 0);
    }
    100% {
        -webkit-transform: translate(300px, 300px);
    }
}

HTML 代码:

<div style="width: 344px; height: 344px; border: 1px solid green; position: relative; overflow: hidden; display: none;">
    <svg id="s1" xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink"
     width="344" height="344" style="width: 100%; height: 100%;">
        
    </svg>  
    <div id="d1" style="position: absolute; width: 272px; height: 112px; left: 0; top: 0;">
        <svg xmlns="http://www.w3.org/2000/svg" 
            xmlns:xlink="http://www.w3.org/1999/xlink"
            width="272" height="112" style="width: 100%; height:100%;">
            <g id="g1">
                <path fill="none" stroke="red" d="M0,0 L10,10 c50,0 50,100 100,100 50,0 50,-100 100,-100 l60,60" z='100'/>
            </g>
        </svg>
    </div>
</div>

注:截图中的各种颜色的方块是使用 JavaScript 代码随机生成的几个 <rect/> 元素。可以参考下面的代码:

var s1 = document.getElementById('s1');
for (var i = 0; i < 10; i++) {
    var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
    rect.setAttribute('x', Math.random() * 350);
    rect.setAttribute('y', Math.random() * 350);
    rect.setAttribute('width', 20 + Math.random() * 50);
    rect.setAttribute('height', 20 + Math.random() * 50);
    rect.setAttribute('fill', 'rgb(' + Math.round(Math.random() * 255) + ','
                                     + Math.round(Math.random() * 255) + ','
                                      + Math.round(Math.random() * 255) + ')');
    s1.appendChild(rect);
}

2 Comments

  1. 雪鹰领主
    雪鹰领主 2015年9月18日

    [围观]。。。。。

  2. bateer
    bateer 2015年11月11日

    从百度点进来的,支持一下

发表评论

电子邮件地址不会被公开。 必填项已用*标注