SVG 路径动画的实现原理

SVG 路径动画的实现原理

svg 路径动画的实现,主要依赖于两个 svg 属性(同样适用CSS),它们分别是:

  • stroke-dasharray : 定义用于绘制形状轮廓的虚线和间隙
  • stroke-dashoffset: stroke-dasharray 的偏移量
html 复制代码
<svg viewBox="0 0 30 12" xmlns="http://www.w3.org/2000/svg">
  <line x1="0" y1="1" x2="30" y2="1"></line>
</svg>
<style>
  svg {
    width: 400px;
    border: 1px solid #333;
  }
  line {
    stroke: white;
    stroke-dasharray: 10;
    animation: move 2s infinite;
  }
  @keyframes move {
    0%,
    100% {
      stroke-dashoffset: 0;
    }
    50% {
      stroke-dashoffset: 10;
    }
  }
</style>

如果 stroke-dashoffsetstroke-dashoffset 以及 路径的长度相同, 就可以实现元素从消失到完整出现的过渡效果。 如下:

css 复制代码
  @keyframes move {
    0%,
    100% {
      stroke-dashoffset: 0;
    }
    50% {
      stroke-dashoffset: 30;
    }
  }

但是有两个问题我们需要解决:

  1. 我们需要知道路径的长度
  2. 我们需要设定动画为变量

第一个问题,我们可以通过svg 元素对象的API 实现:getTotalLength()

getTotalLength()

js 复制代码
document.querySelector('line').getTotalLength();// 30

第二个问题,我们可以通过 EL.style.setProperty 和 CSS 变量引用var 来解决:

style.setProperty

示例:

js 复制代码
// js
const p = document.querySelector('line')
p.style.setProperty('--l', p.getTotalLength())
css 复制代码
/* css */
  line {
    stroke: white;
    stroke-dasharray: var(--l);
    animation: move 2s infinite;
  }
  @keyframes move {
    0%,
    100% {
      stroke-dashoffset: 0;
    }
    50% {
      stroke-dashoffset: var(--l);
    }
  }

多路径示例

html 复制代码
  <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
    <g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
      color="currentColor">
      <path class="p" d="M22 12c0 5.523-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2s10 4.477 10 10" />
      <path class="p" d="M2 12c2.28 2.429 5.91 4 10 4s7.72-1.571 10-4M12 2v20" />
      <path class="p"
        d="M5.156 5c-.382 1.5-.116 4 1.41 6c1.605 2.103 2.616 5-1.197 8M18.844 5c.382 1.5.116 4-1.41 6c-1.605 2.103-2.616 5 1.197 8" />
    </g>
  </svg>
html 复制代码
<style>
  svg {
    width: 400px;
    border: 1px solid #333;
    color: white;
  }
  .p {
    stroke: white;
    stroke-dasharray: var(--l);
    animation: move 2s infinite;
  }
  @keyframes move {
    0%,
    100% {
      stroke-dashoffset: 0;
    }
    50% {
      stroke-dashoffset: var(--l);
    }
  }
</style>
html 复制代码
<script>
  const paths = document.querySelectorAll('.p')
  paths.forEach(p => {
    p.style.setProperty('--l', p.getTotalLength())
  })
</script>

多元素示例

相关推荐
天蓝色的鱼鱼24 分钟前
关于 CSS 你可能不知道的属性,但关键时刻很有用
前端·css
用户059540174468 小时前
向量库静默丢数据踩坑实录:Playwright 端到端测试让我排查了72小时
前端·css
ZhengEnCi1 天前
Q06-导航按钮高级拟态玻璃效果构建完全指南
前端·css
用户059540174461 天前
Redis持久化踩坑实录:这个数据丢失Bug让我排查了6小时
前端·css
用户059540174462 天前
Redis记忆存储故障恢复测试踩坑实录:手动测试让我漏掉了2个一致性Bug
前端·css
用户059540174462 天前
用了3年Mock,才发现Redis记忆存储的测试一直漏掉了60%的边界场景
前端·css
用户059540174463 天前
用了6个月LangChain,才发现AI Agent的记忆存储一直有坑——写了23个Pytest用例才彻底修好
前端·css
用户059540174463 天前
把LLM记忆测试从手工脚本换成Pytest参数化,回归时间从2小时降到10分钟
前端·css
用户059540174464 天前
Redis缓存一致性踩坑实录:线上故障排查6小时,我用pytest+内存快照把它永久关进了笼子
前端·css
llllk5 天前
新手向逐段讲解
css