SVG 动画原来这么简单

2021/10/18

SVG 线条动画一般都基于 stroke 的stroke-dasharray和stroke-dashoffset两个属性来实现。

先快速了解下这两个属性的作用。

stroke-dasharray 主要用来实现虚线效果。属性值可以是一个数字,也可以是多个数(逗号隔开),百分数,负数无效。

stroke-dasharray: 10;
stroke-dasharray: 10, 20, 30;

如何理解属性值,基于官方的解释,这里说一下我觉得更容易理解的方式。

不管几个数,定义的数可以理解为一组,然后是不断重复的。比如上面的可以理解为:

stroke-dasharray: 10,10,10,10,10,10,10,10,10,10,10,10,...;
stroke-dasharray: 10,20,30, 10,20,30, 10,20,30, 10,20,30...;

奇数位置的数代表实线的长度,偶数位置的为虚线的长度。也就是第一个是实线的长度,第二个数是虚线的长度,第三个数是实线的长度......

下面通过示例能更清晰理解。图中的背景为10*10的方块。

stroke-dashoffset 是绘制起点的偏移量。属性值可以是数字、负数,百分数。

stroke-dashoffset: 10;
stroke-dashoffset: -20;
stroke-dashoffset: 10%;

按照我们的经验去理解,正值就是向右偏移量,负值向左偏移量。

在浏览器中连续调整值可以非常清晰的看到其效果。

可以看到正值表现为向左移动,而负值则表现为向右移动,这个和我们理解刚好相反,之前看了网上各种文章对于这个解释的也不是很清楚,SVG标准文档里面甚至还有计算公式,都不能很好理解。

回到它的定义——绘制起点的偏移量,那么如果是正值,绘制起点需要向右移动对应的值,比如stroke-dashoffset: 8; 就是绘制起点向右移8,那么此时相对于 stroke-dashoffset: 0; 可以看做是把线条往后移动8,这也是为什么我们看到的效果是向左移动。

最后来说一下基于这两个属性怎么去做一些动画,其实上面视频中已经可以看到 stroke-dashoffset 的变化已经可以做出一些动画来。比如一条流动的虚线就可以非常简单的实现。

<line class="flow-right" x1="50" y1="40" x2="360" y2="40"
                  shape-rendering="crispEdges" stroke-dasharray="10"
                  style="stroke:rgb(0,0,0,.5);stroke-width:1" />

<line class="flow-left" x1="50" y1="50" x2="360" y2="50"
      shape-rendering="crispEdges" stroke-dasharray="10"
      style="stroke:rgb(0,0,0,.5);stroke-width:1" />

.flow-right {
    stroke-dashoffset: -20;
    animation: flow 1s linear infinite;
}
 .flow-left {
    stroke-dashoffset: 20;
    animation: flow 1s linear infinite;
}

@keyframes flow {
    to {
        stroke-dashoffset: 0;
    }
}

用在圆环上,可以很方便实现一个 loading效果


<circle class="circle" cx="100" cy="150" r="40" stroke="#888"
                    stroke-dasharray="125" stroke-width="1" fill="none" />
<style>
.circle {
    stroke-dashoffset: 250;
    animation: circle 1s linear infinite;
}
@keyframes circle {
    to {
        stroke-dashoffset: 0;
    }
}
</style>

使用 stroke-dasharray 可以快速实现环形进度的效果。


<circle class="progress" cx="200" cy="150" r="40" stroke="#888"
                    stroke-width="1" fill="none" />
<style>
.progress {
    stroke-dasharray: 0,250;
    animation: progress 10s linear infinite;
}
@keyframes progress {
    to {
        stroke-dasharray: 250,0;
    }
}
</style>

两个属性组合还可以做出更多的效果。

当然使用 CSS 在IE兼容性有一定问题,如果不考虑IE的兼容性问题,还是一个实现SVG动画的不错的选择。

原创文章,持续完善中,转载请注明出处。本文地址: https://www.qinshenxue.com/article/svg-animation
关注我的公众号:前端路迹