G4:GSAP SVG 动画——DrawSVG 描边、MorphSVG 变形与路径动画

GSAP 动画实战系列 系列总览 | G1 Tween & Timeline | G2 ScrollTrigger | G3 文本动画 | G4 SVG 动画 ← 本文 | G5 GSAP + React | G6 AI 项目实战 | G7 社区案例


# GSAP SVG 动画 ## DrawSVG - stroke-dasharray 原理 - 线条自绘效果 - 循环描边动画 ## MorphSVG - 形状之间的平滑变形 - findShapeIndex 自动匹配 - 多步骤形态变换 ## MotionPath - 元素沿路径移动 - 自动旋转对齐 - 贝塞尔曲线路径 ## AI 可视化应用 - 神经网络连线动画 - 数据流向可视化 - Logo 动态展示

SVG 动画是 GSAP 的高级战场。三个核心插件构成了完整的 SVG 动画工具集:

插件 功能 许可
DrawSVG 控制 SVG stroke 的绘制/擦除 免费(原付费,Webflow 收购后免费)
MorphSVG 在不同 SVG 形状之间平滑变形 免费(原付费,Webflow 收购后免费)
MotionPath 让元素沿 SVG 路径移动 免费

1. DrawSVG——线条自绘

🎬 DrawSVG 描边效果演示CodePen | MorphSVG 变形演示CodePen | MotionPath 演示CodePen

DrawSVG 的原理是操纵 SVG 的 stroke-dasharraystroke-dashoffset。它让线条看起来像在"自动绘制"。

1.1 基础用法

<svg viewBox="0 0 200 200">
  <path id="myLine" d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"
        stroke="#8B5CF6" stroke-width="3" fill="none"/>
</svg>
import { DrawSVGPlugin } from 'gsap/DrawSVGPlugin'
gsap.registerPlugin(DrawSVGPlugin)

gsap.from('#myLine', {
  drawSVG: 0,        // 从 0%(不显示)到 100%(完整)
  duration: 2,
  ease: 'power2.inOut',
})

1.2 往返描边

gsap.fromTo('#path', 
  { drawSVG: 0 },
  { 
    drawSVG: '100%',
    duration: 2,
    repeat: -1,
    yoyo: true,
    repeatDelay: 0.5,
    ease: 'power3.inOut',
  }
)

1.3 多路径组合

const tl = gsap.timeline({ defaults: { ease: 'power2.inOut' } })

tl.from('#line1', { drawSVG: 0, duration: 1 })
  .from('#line2', { drawSVG: 0, duration: 0.8 }, '-=0.5')
  .from('#line3', { drawSVG: 0, duration: 0.6 }, '-=0.4')

1.4 DrawSVG + ScrollTrigger——滚动触发描边

当用户滚动到图标区域时,图标自动绘制:

gsap.from('#logo-path', {
  drawSVG: 0,
  duration: 2,
  scrollTrigger: {
    trigger: '#logo-container',
    start: 'top 80%',
    toggleActions: 'play none none reverse',
  }
})

2. MorphSVG——形状变形

MorphSVG 让一个 SVG 形状平滑变化为另一个形状。它的工作原理是将两个 path 的数据插值。

2.1 基础变形

<svg viewBox="0 0 100 100">
  <path id="shape" d="M 20 50 A 30 30 0 1 1 80 50 A 30 30 0 1 1 20 50 Z" 
        fill="#8B5CF6"/>
</svg>
import { MorphSVGPlugin } from 'gsap/MorphSVGPlugin'
gsap.registerPlugin(MorphSVGPlugin)

gsap.to('#shape', {
  morphSVG: 'M 10 80 L 50 10 L 90 80 Z',  // 变成三角形
  duration: 1.5,
  ease: 'power2.inOut',
  repeat: -1,
  yoyo: true,
})

2.2 findShapeIndex——自动寻找最佳路径

如果目标 path 的节点数和结构不同,MorphSVG 需要你指定 shapeIndex 来正确匹配节点。但你可以让它自动找:

gsap.to('#shape', {
  morphSVG: {
    shape: '#targetShape',                    // 目标 SVG 元素的 id
    shapeIndex: 'auto',                        // 自动匹配
    // 或者手动:shapeIndex: [0, 1, 2, 3]
  },
  duration: 2,
})

2.3 多步骤变形

const shapes = ['#shape1', '#shape2', '#shape3', '#shape4']
let current = 0

function morphNext() {
  current = (current + 1) % shapes.length
  gsap.to('#morph-element', {
    morphSVG: shapes[current],
    duration: 1.5,
    ease: 'elastic.out(1, 0.5)',
    onComplete: () => setTimeout(morphNext, 1000),
  })
}

morphNext()

2.4 AI 场景:数据流形态变换

在 AI 可视化中,可以让图标根据数据状态变形——比如从"思考"图标变成"完成"图标:

function morphByStatus(status) {
  const shapes = {
    idle: '#shape-idle',
    thinking: '#shape-thinking',
    done: '#shape-done',
    error: '#shape-error',
  }
  gsap.to('#status-icon', {
    morphSVG: shapes[status] || shapes.idle,
    duration: 0.8,
    ease: 'power2.inOut',
  })
}

3. MotionPath——沿路径运动

MotionPath 让元素沿着 SVG 路径移动,可以自动旋转对齐路径方向。

3.1 基础路径跟随

<svg viewBox="0 0 500 300">
  <path id="track" d="M 50 250 C 50 50, 450 50, 450 250"
        fill="none" stroke="#333" stroke-width="1" stroke-dasharray="5 5"/>
  <circle id="dot" r="10" fill="#8B5CF6"/>
</svg>
import { MotionPathPlugin } from 'gsap/MotionPathPlugin'
gsap.registerPlugin(MotionPathPlugin)

gsap.to('#dot', {
  duration: 3,
  repeat: -1,
  motionPath: {
    path: '#track',
    align: '#track',          // 自动旋转对齐路径方向
    autoRotate: true,         // 元素自身旋转跟随路径切线
    alignOrigin: [0.5, 0.5],  // 对齐原点在元素中心
  },
  ease: 'power2.inOut',
})

3.2 偏移起始位置

motionPath: {
  path: '#track',
  start: 0.25,    // 从路径 25% 处开始
  end: 0.75,      // 到路径 75% 处结束
}

3.3 AI 可视化——数据包沿网络路径传输

function animateDataPacket(nodeA, nodeB) {
  // 动态创建两点之间的曲线路径
  const path = document.querySelector('#data-path')
  path.setAttribute('d', `M ${nodeA.x} ${nodeA.y} Q ${(nodeA.x+nodeB.x)/2} ${nodeA.y-50} ${nodeB.x} ${nodeB.y}`)
  
  return gsap.to('.packet', {
    duration: 2,
    motionPath: {
      path: '#data-path',
      autoRotate: true,
    },
    scale: 0.6,
    opacity: 0,
    onComplete: () => gsap.set('.packet', { scale: 1, opacity: 1 })
  })
}

这在展示神经网络推理过程、API 调用链、微服务通信等 AI/分布式系统场景中非常出彩。

4. GSAP 与 SVG 属性的通用动画

即使不用专用插件,GSAP 也能直接动画 SVG 属性:

// 改变圆的半径和位置
gsap.to('circle', {
  attr: { r: 50, cx: 200, cy: 150 },
  duration: 1.5,
  ease: 'power3.out',
})

// 改变路径的描边颜色和宽度
gsap.to('path', {
  stroke: '#ff6b6b',
  strokeWidth: 5,
  fill: 'rgba(139, 92, 246, 0.2)',
  duration: 1,
})

// transformOrigin 在 SVG 中
gsap.to('rect', {
  rotation: 360,
  transformOrigin: '50% 50%',  // SVG 中用百分比
  repeat: -1,
  duration: 3,
})

5. 生产级组合案例:动态 Logo 动画

结合 DrawSVG + MorphSVG + MotionPath 做一个完整的 logo 动画:

const masterTL = gsap.timeline({ repeat: -1, repeatDelay: 2 })

// 第 1 段:描边绘制 Logo 轮廓
masterTL.from('#logo-outline', {
  drawSVG: 0,
  duration: 2.5,
  ease: 'power2.inOut',
})

// 第 2 段:圆点沿路径飞到 Logo 中心
masterTL.to('#dot', {
  motionPath: {
    path: '#logo-track',
    autoRotate: true,
  },
  duration: 1.5,
  ease: 'power3.in',
}, '-=1')

// 第 3 段:Logo 形状变形
masterTL.to('#logo-shape', {
  morphSVG: '#logo-alternate',
  duration: 1.2,
  ease: 'elastic.out(1, 0.4)',
}, '+=0.5')

6. 踩坑记录

  1. MorphSVG 要求两个 path 的节点数一致——用 findShapeIndex()shapeIndex: 'auto' 来让插件自动匹配。

  2. SVG 中的 transformOrigin——在 SVG 中 transformOrigin 是相对于 SVG viewBox 的,而不是相对于元素的 CSS 盒模型。用百分比最安全。

  3. MotionPath 的 alignalignOrigin 只对 SVG 路径有效——不要把 CSS 的 transform 和对齐一起用,容易冲突。

  4. DrawSVG 移动端性能——复杂路径(数千个点)在移动端可能卡顿,考虑用 will-change: stroke-dashoffset

  5. 许可——DrawSVG 和 MorphSVG 自 Webflow 收购 GSAP 后已全部免费,包括商业用途。直接从 npm 安装即可,无需会员或 token。


下一篇:G5 GSAP + React——现代框架集成最佳实践

实操清单

  • 安装并在项目中 import { DrawSVGPlugin } from 'gsap/DrawSVGPlugin',调用 gsap.registerPlugin(DrawSVGPlugin) 注册插件
  • 创建一个带 strokefill="none" 的 SVG <path>,用 gsap.from('#myLine', { drawSVG: 0, duration: 2 }) 实现线条自绘效果
  • drawSVG: '100%' 配合 repeat: -1, yoyo: true 实现往返描边循环动画
  • 用 Timeline 对多条路径(#line1#line2#line3)依次叠加描边,通过负偏移('-=0.5')实现流畅衔接
  • 将 DrawSVG 与 ScrollTrigger 结合,配置 toggleActions: 'play none none reverse',实现滚动到视口时自动绘制 logo
  • 安装并注册 MorphSVGPlugin,用 morphSVG 属性将一个圆弧路径变形为三角形,配合 repeat: -1, yoyo: true 循环
  • shapeIndex: 'auto' 处理节点数不同的两个路径之间的变形,观察自动匹配效果
  • 实现多步骤变形:维护一个 shapes 数组,在 onComplete 回调中递归调用 morphNext() 切换形态
  • 安装并注册 MotionPathPlugin,让一个 <circle> 沿虚线 <path> 轨迹循环运动,并开启 autoRotate: true
  • motionPathstart / end 参数限制元素只在路径的某段区间内运动
  • 综合三个插件,搭建 masterTimeline:先 DrawSVG 描边轮廓,再 MotionPath 引导圆点飞入,最后 MorphSVG 变形收尾
  • gsap.to('circle', { attr: { r: 50, cx: 200 }, duration: 1.5 }) 直接动画 SVG 原生属性,验证无需额外插件