形状变形

MorphSVG

MorphSVG SVG 变形 路径变形 形状过渡 Shape Morphing Path Morph

让一个 SVG 路径平滑变成另一个形状;GSAP 的 MorphSVG 插件会自动处理两条路径锚点数量不同的问题。

又称:SVG 变形 · 路径变形 · 形状过渡 · Shape Morphing · Path Morph

  • GSAP
  • Claude / Cursor
morphSVG: circle → star → heart

Prompt 片段

  • Claude / Cursor
    用 GSAP MorphSVGPlugin 做图标切换:同一个 path 依次变成星形、心形再变回圆形,每段 duration 1,ease expo.inOut,同时过渡 fill 颜色,timeline 设 repeat: -1。
  • Claude / Cursor源和目标用同一坐标系,变形才不会位移
    把播放按钮的三角形 path 变形为暂停图标,点击时 morphSVG 到暂停路径,再点击变回;两条路径都放在 viewBox 0 0 24 24 的同一坐标系里。
  • Claude / Cursor
    变形过程中形状扭曲得厉害,帮我调整 morphSVG 的 shapeIndex,或把 type 改成 'rotational' 试试效果。

是什么

形状变形(MorphSVG)是让一个 SVG 形状平滑过渡成另一个形状的动画。浏览器原生只能在锚点数量和命令结构一致的两条路径之间插值,实际的图标几乎不可能满足这个条件。MorphSVGPlugin 会自动补齐锚点、匹配起点,让任意两条路径都能过渡。它随 gsap 包免费提供,从 gsap/MorphSVGPlugin 导入。

上方演示只有一个 path 元素:先从圆形变成五角星,再变成心形,最后回到圆形,填充色同步从紫色过渡到橙色、红色。每段变形使用 expo.inOut,中间停顿 0.6 秒。

核心参数

写法 含义
morphSVG: '#star' 目标可以是选择器、元素或路径字符串
shape 对象写法中的目标形状
shapeIndex 调整起点对应关系,用来修正扭曲
type 'linear''rotational',后者适合有旋转感的变形
map 锚点匹配策略:'size''position''complexity'
MorphSVGPlugin.convertToPath() 把 circle、rect 等转成 path

代码示例

import { gsap } from 'gsap';
import { MorphSVGPlugin } from 'gsap/MorphSVGPlugin';

gsap.registerPlugin(MorphSVGPlugin);

// 三条路径都在 viewBox="0 0 100 100" 中
const CIRCLE = 'M50,10 C72.1,10 90,27.9 90,50 C90,72.1 72.1,90 50,90 C27.9,90 10,72.1 10,50 C10,27.9 27.9,10 50,10 Z';
const STAR = 'M50,8 L61.8,37.6 L93.7,39.2 L69,59.4 L77,90.2 L50,73 L23,90.2 L31,59.4 L6.3,39.2 L38.2,37.6 Z';
const HEART = 'M50,88 C50,88 10,62 10,36 C10,22 21,12 33,12 C41,12 47,17 50,23 C53,17 59,12 67,12 C79,12 90,22 90,36 C90,62 50,88 50,88 Z';

const tl = gsap.timeline({ repeat: -1, repeatDelay: 0.6, defaults: { duration: 1, ease: 'expo.inOut' } });
tl.to('#shape', { morphSVG: STAR, fill: '#ff9f0a' })
  .to('#shape', { morphSVG: HEART, fill: '#ff375f' }, '+=0.6')
  .to('#shape', { morphSVG: CIRCLE, fill: '#bf5af2' }, '+=0.6');

什么时候用

  • 图标状态切换:播放与暂停、菜单与关闭、加号与对勾。
  • 插画、Logo 的变形转场。
  • 数据可视化中形状之间的过渡。

常见误区

  • 对 circle、rect 等非 path 元素直接变形:先用 convertToPath() 转成 path。
  • 源和目标来自不同画板、坐标系不一致:变形时会连带产生位移和缩放。
  • 形状差异太大:插件能保证过渡,但中间帧可能很难看。设计时让形状的重心和大小接近,效果更自然。
esc