svg stroke-dasharray和stroke-dashoffset理解

1,747 阅读2分钟

SVG 中常常使用 path 的 stroke-dasharray 和 stroke-dashoffset 属性来实现描边动画效果。

stroke-dasharray

stroke-dasharray 属性用来给 path 添加虚线效果。例如有一条直线路径,假设宽度为10px,填充色为蓝色,长度为400px:

<svg 
   viewBox="0 0 400 400" 
   width="400" 
   height="400"  
   style="border:1px solid #409eff">
   <path fill="none" stroke="#409EFF" stroke-width="10"
      d="M0 200 L400 200">
    </path>
 <svg>

效果如图:

因为设置了stroke,所以整个路径完全被填充了,但是如果设置了stroke-dasharray则可以制作成虚线填充效果,例如stroke-dasharray ="50",则表示先使用stroke设置的颜色填充50px,然后空出50px,然后再次填充50px,即填充50px,空出50px,再次填充50px,再次空出50px,如此循环往复。

<path 
  fill="none" 
  stroke="#409EFF" 
  stroke-dasharray="50" 
  stroke-width="10"
  d="M0 200 L400 200">
</path>

也可以设置多个值,中间用空格隔开

stroke-dasharray="50 30"

表示按照填充50,空出30规则循环填充

stroke-dashoffset

上述stroke-dasharray不管怎么设置,他始终从路径的最开始开始填充,即最左边0处开始填充,如果不想让其在开始处填充,则可以设置stroke-dashoffset偏移量。例如下面设置了-10,则表示在路径开始处之后的10之后开始按照50 30填充。

<path 
    fill="none" 
    stroke="#409EFF" 
    stroke-dasharray="50 30"
    stroke-dashoffset="-10" 
    stroke-width="10"
      d="M0 200 L400 200">
    </path>

如果设置成正10会怎样?

stroke-dashoffset="10" 

设置成正数则往左偏移10px开始绘制,即有一部分会被遮住。

描边动画

结合stroke-dasharray 和 stroke-dashoffset 可以实现描边动画效果。

假如有个path,长度为100,设置 stroke-dasharray ="100 100",则效果如下图

虚线部分的100其实被完全隐藏。 假如再设置一下stroke-dashoffset = 100,则效果图为下面所示

此时path则完全没有被实线填充。

当不断减少stroke-dashoffset偏移量时就可以实现描边动画了。

<svg>
   <path 
      d="m108.300003,70.849998c0,-1 1.458801,-1.693436 2,-3c0.382683,-0.923882 1.292892,-2.292892 2,-3c0.707108,-0.707108 0.692551,-1.186008 2,-3c0.826904,-1.14727 2,-1 3,-2c1,-1 2,-1 3,-2c1,-1 2.458801,-1.693436 3,-3c0.382683,-0.923878 0.617317,-2.076122 1,-3c0.541199,-1.306564 1,-2 2,-3c1,-1 2,-3 2,-4c0,0 -0.306564,-1.458805 1,-2c0.923874,-0.382683 2,-2 2,-2c0,-1 1,-3 1,-4c0,0 0,-1 0,-2c0,-1 0,-2 0,-2c0,-0.999998 1,-0.999998 1,1c0,3 0,3 0,4c0,2 -0.229752,3.026752 0,4c0.513748,2.17625 1.95517,2.549156 3,6c0.28978,0.957092 0.346191,3.70546 2,6c1.307449,1.813992 2,3 2,3c0,2 -0.306564,4.458805 1,5c0.923874,0.382683 1.292892,2.292892 2,3c0.707108,0.707108 1.292892,2.292892 2,3c0.707108,0.707108 2.907791,1.496223 7,2c5.955048,0.733101 10,0 12,0c0,0 1,0 2,0c2,0 4,0 6,0c3,0 4,0 6,0c2,0 3,0 6,0c0,0 2,0 3,0c1,0 2,0 3,0c1,0 1.707108,2.292892 1,3c-0.707108,0.707108 -2.292892,1.292892 -3,2c-0.707108,0.707108 -1,2 -1,2c-1,0 -2.693436,2.458801 -4,3c-0.923874,0.382683 -2.693436,1.458801 -4,2c-1.847763,0.765366 -2.907791,2.496223 -7,3c-1.985016,0.24437 -3.61731,1.076118 -4,2c-0.541199,1.306564 -3,1 -4,1c-1,0 -1,1 -2,1c-1,0 -1.292892,1.292892 -2,2c-0.707108,0.707108 -1,1 -1,2c0,1 0,2 0,4c0,1 1,4 1,7c0,1 -0.414215,3.585785 1,5c0.707108,0.707108 1,2 1,3c0,1 -0.210144,2.078438 1,5c0.855713,2.065857 2,4 2,5c0,1 1,3 1,3c0,1 0,3 0,4.000008c0,0 0,1 0,3c0,1 0,2 0,3c0,2 0.707108,2.292892 0,3c-1.414215,1.414215 -1.852737,-0.173096 -3,-1c-1.813995,-1.307449 -3,-2 -5,-4c-2,-2 -4,-4 -4,-4c-1,-2.000008 -1.693436,-4.458809 -3,-5.000008c-0.923874,-0.382683 -3,-3 -3,-3c-1,-1 -3.173096,-2.85273 -4,-4c-1.307449,-1.813995 -2,-2 -3,-3c-1,-1 -1.917603,-1.386871 -3,-4c-0.38269,-0.923882 -1.458801,-0.693436 -2,-2c-0.38269,-0.923882 -1.292892,-1.292892 -2,-2c-0.707108,-0.707108 -1,-1 -2,-1c-1,0 -3.292892,0.292892 -4,1c-0.707108,0.707108 -2.70546,0.346191 -5,2c-3.627983,2.614906 -6.878555,4.493462 -10,5c-0.987091,0.160179 -3.159279,0.610649 -6,2c-3.238922,1.584106 -5.823746,4.486259 -8,5c-0.973251,0.229752 -3.186005,0.692551 -5,2c-2.29454,1.653809 -3.878677,0.878677 -6,3c-0.707108,0.707108 -2,2 -3,2c-1,0 -0.693436,1.458809 -2,2.000008c-0.923882,0.38269 -1,0 -1,-1.000008c0,-1 0,-2 0,-3c0,-1 0,-2 0,-4c0,0 0,-1 0,-2c0,-2 -0.307449,-2.186005 1,-4c0.826904,-1.14727 0.617317,-4.076118 1,-5c0.541199,-1.306564 1,-1 2,-2c1,-1 1.292892,-1.292892 2,-2c0.707108,-0.707108 0.292892,-1.292892 1,-2c0.707108,-0.707108 2.076118,-2.617317 3,-3c1.306564,-0.541199 2,-2 2,-3c0,-1 0.765366,-1.152245 0,-3c-0.541199,-1.306564 -4,-2 -6,-4c-1,-1 -2.878555,-2.493462 -6,-3c-0.987091,-0.160179 -1.415291,-0.188759 -2,-1c-1.849014,-2.565376 -4,-2 -6,-2c-2,0 -1.878555,-2.493462 -5,-3c-0.987091,-0.160179 -2,0 -4,-1c0,0 -1.528145,-1.118324 -2.000004,-2c-1.701309,-3.178925 -3.152241,-1.234634 -5,-2c-1.306564,-0.541199 1.005798,-0.813591 4,-1c8.04668,-0.500969 9.076122,-0.617317 10.000004,-1c1.306564,-0.541199 2.076118,-0.617317 3,-1c1.306564,-0.541199 2,-1 2,-1c0,-1 2,-1 3,-1c0,0 1,0 2,0c1,0 3,0 6,0c0,0 1,0 3,0c1,0 1,0 2,0c1,0 2,0 3,0c0,0 1,0 2,0c1,0 2,0 2,0c1,0 2,0 3,0c1,0 1,-1 2,-1l2,0l1,-1l0,-1" 
      id="svg_2" stroke-width="2" stroke="red" fill="none"/>
 </svg>

js部分:

const el = document.querySelector('#svg_2')
const len = el.getTotalLength()
el.style['stroke-dasharray'] = len
el.style['stroke-dashoffset'] = len
let timer = null
timer = setInterval(()=>{
  if(el.style['stroke-dashoffset']>0){
    el.style['stroke-dashoffset'] -= 3
  }else{
    clearInterval(timer)
  }
},16)

完!