Skip to content
On this page

描边动画

由于 SVG 是一种 XML 格式的文档,和 HTML 中的 DOM 类似,所以 SVG 也能通过 CSS 执行动画效果。

这个动画是由一个颜色填充动画、描边线条动画和放大动画这三个动画组成。

描边动画原理

SVG 描边动画密切相关的3个属性

  • stroke:用来定义边框的颜色

  • stroke-dasharray:定义 dashgap 的长度。它主要是通过使用逗号 , 来分隔实线和间隔的值。其实就是用来实现 CSS 中边框虚线的效果。和 CSS 中的 dash 的效果一样。例如:stroke-dasharray="5, 5" 表示,按照实线为 5,间隔为 5 的排布重复下去。

  • stroke-dashoffset:用来设置 dasharray 定义 dash 线条开始的位置。值可以为 number || percentage。百分数是相对于 SVG 的 viewport。通常结合 dasharray 可以实现描边动画效果。

介绍完关于 path 的所有 stroke 属性之后,下面就来解释下 SVG 线条描边动画的原理。简单来说,就是通过 stroke-dashoffsetstroke-dasharray 来做。主要是以下两个步骤:

  • 通过 dasharray 将实线部分增加至全长。比如:一条 path 的长度为 100,如果把 SVG 中的 pathstroke-dasharray 的值设置为 100, 100,即表示这条 path 将会按照实线 100,间隔 100 的排布重复下去。所以默认的情况下,我们只会看到一条 100 长度的实线,间隔 100 的线段由于已经在画布外,所以是不可见的。

  • 通过 stroke-dashoffset 来移动新增的实线部分,造成线段移动的效果。比如由:stroke-dashoffset: 500 变为 stroke-dashoffset: 0

通过简单演示下:

html
<svg x="0px" y="0px" width="300px" height="100px" viewBox="0 0 300 100" class="svg1">
  <line x1="20" y1="50" x2="200" y2="50" stroke="#000" stroke-width="1" ></line>
</svg>

样式为:

css
.svg1 line {
  stroke-dasharray: 100, 100;
  stroke-dashoffset: 100;
}

因为 stroke-dasharraystroke-dashoffset 的值都是 100,所以这条线段在网页初始化的时候,是看不见的。当我们把 stroke-dashoffset 的值设置为0的时候,它就可以显示出来,如下动图所示:

svglin.gif

修改 CSS

css
.svg1 line {
    stroke-dasharray: 100, 100;
    stroke-dashoffset: 100;
    transition: all 1s linear;
}

修改 stroke-dashoffset 值,动画效果就完成了。

示例

html
<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
  <circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none"/>
  <path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
</svg>

初始状态是元素都没有显示,需要描边的是中间勾;初始化的时候只需要把 path 元素的 stroke-dasharrystorke-dashoffset 的值设置为 path 长度就行

css
.checkmark__circle {
  fill: #7ac142;
}

.checkmark {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: block;
  stroke-width: 2;
  stroke: #fff;
  box-shadow: inset 0px 0px 0px #7ac142; 
}
.checkmark__check {
  transform-origin: 50% 50%;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
}

path 长度怎么获取?

js
var path = document.querySelector('path');
var length = path.getTotalLength();

线的描边动画

css
@keyframes stroke {
  100% {
    stroke-dashoffset: 0;
  }
}

添加样式

css
.checkmark__check {
  transform-origin: 50% 50%;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
  animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;
}

效果如下:

svgd.gif

代码