DEV Community

NikiMunger
NikiMunger

Posted on

进度条svg动画

<svg width="300" height="100">
  <path id="p"
        d="M10 50 L290 50"
        stroke="green"
        stroke-width="4"
        fill="none" />
</svg>

<script>
  const p = document.getElementById('p');
  const len = p.getTotalLength();

  p.style.strokeDasharray = len;
  p.style.strokeDashoffset = len;

  void p.getBoundingClientRect();
  p.style.transition = "stroke-dashoffset 2s";
  p.style.strokeDashoffset = 0;

</script>
Enter fullscreen mode Exit fullscreen mode

d="M10 50 L290 50"

包含 两个指令:

  • M10 50
    M = moveTo
    作用:将画笔移动到 (10, 50),不画线。

  • L290 50
    L = lineTo
    作用:从当前点画一条直线到 (290, 50)

作用:

  1. 告诉 SVG 要画哪一条线
  2. 决定路径的长度,用于动画计算

思路

  1. 通过p.style.strokeDasharray = len;画虚线

    虚线: 线段 空白 线段 空白 ...
    线段和空白的长度都是len

  2. 通过p.style.strokeDashoffset = len;使虚线的起点向前移动 len 的长度

    移动前:
    线段 空白 线段 空白 ...

    移动后:
    (线段) 空白 线段 空白 ...
    括号中的线段向前移动,移出了视口,所以表现为空白

  3. void p.getBoundingClientRect();强制浏览器 reflow
    确保浏览器将p.style.strokeDashoffset的值先设为len,再设为0,
    而不是因为样式批处理优化直接将p.style.strokeDashoffset的值设置为0

  4. 动画

    p.style.transition = "stroke-dashoffset 2s";
    p.style.strokeDashoffset = 0;
    

    p.style.strokeDashoffset从len变为0。
    逐渐增长的进度条,是因为随着p.style.strokeDashoffset的减小,移出窗口的第一段线段逐渐向后移动变得可见。

Top comments (0)