Morphing 与路径动画
GSAP 的 Morphing 和路径动画功能,用于创建 SVG 形状变形和沿路径运动的动画效果。
📚 Morphing 简介
什么是 Morphing?
Morphing(变形)是指将一个形状平滑地转换为另一个形状,常用于 SVG 动画。
应用场景
- Logo 动画
- 图标转换
- 形状过渡
- 数据可视化
🚀 SVG Morphing
基础 Morphing
// 需要 MorphSVGPlugin(付费插件)
gsap.to("#path1", {
morphSVG: "#path2",
duration: 1
});使用路径字符串
gsap.to("#path", {
morphSVG: "M0,0 L100,0 L100,100 L0,100 Z",
duration: 1
});🎯 MotionPathPlugin(路径动画)
MotionPathPlugin 是 GSAP 的免费插件,用于创建沿路径运动的动画。
安装与引入
import { gsap } from "gsap";
import { MotionPathPlugin } from "gsap/MotionPathPlugin";
gsap.registerPlugin(MotionPathPlugin);基础用法
// 沿 SVG 路径运动
gsap.to(".box", {
motionPath: {
path: "#path", // SVG 路径 ID
alignOrigin: [0.5, 0.5] // 对齐原点
},
duration: 2
});使用路径字符串
gsap.to(".box", {
motionPath: {
path: "M0,0 Q50,50 100,0 T200,0", // SVG 路径字符串
autoRotate: true // 自动旋转
},
duration: 2
});🎨 MotionPathPlugin 配置
path(路径)
motionPath: {
path: "#svg-path", // SVG 路径元素
// 或
path: "M0,0 L100,100", // 路径字符串
// 或
path: [{x: 0, y: 0}, {x: 100, y: 100}] // 点数组
}autoRotate(自动旋转)
motionPath: {
path: "#path",
autoRotate: true, // 沿路径方向旋转
autoRotate: 90 // 旋转偏移角度
}alignOrigin(对齐原点)
motionPath: {
path: "#path",
alignOrigin: [0.5, 0.5] // [x, y] 对齐点(0-1)
}start/end(起始和结束位置)
motionPath: {
path: "#path",
start: 0, // 起始位置(0-1)
end: 1 // 结束位置(0-1)
}🎬 实战案例
案例 1:沿曲线运动
gsap.to(".ball", {
motionPath: {
path: "M0,0 Q50,-50 100,0 T200,0",
autoRotate: true
},
duration: 2,
repeat: -1,
ease: "none"
});案例 2:圆形轨道
<svg>
<circle id="orbit" cx="100" cy="100" r="50" fill="none" stroke="#ccc"/>
</svg>gsap.to(".planet", {
motionPath: {
path: "#orbit",
autoRotate: true
},
duration: 3,
repeat: -1,
ease: "none"
});案例 3:复杂路径动画
const complexPath = "M0,0 C50,50 150,50 200,0 S350,-50 400,0";
gsap.to(".element", {
motionPath: {
path: complexPath,
autoRotate: true,
alignOrigin: [0.5, 0.5]
},
duration: 4,
ease: "power2.inOut"
});案例 4:往返路径动画
const tl = gsap.timeline({ repeat: -1, yoyo: true });
tl.to(".box", {
motionPath: {
path: "#path",
autoRotate: true
},
duration: 2,
ease: "power2.inOut"
});案例 5:多个元素沿同一路径
const path = "M0,0 Q50,50 100,0";
gsap.utils.toArray(".item").forEach((item, i) => {
gsap.to(item, {
motionPath: {
path: path,
start: i * 0.2, // 错开起始位置
end: (i * 0.2) + 0.8
},
duration: 2,
repeat: -1,
ease: "none"
});
});🎨 SVG 路径动画技巧
路径字符串格式
// M = Move to(移动到)
// L = Line to(直线到)
// C = Curve to(三次贝塞尔曲线)
// Q = Quadratic curve to(二次贝塞尔曲线)
// Z = Close path(闭合路径)
const path = "M0,0 L100,0 L100,100 L0,100 Z"; // 矩形
const path = "M50,0 A50,50 0 1,1 50,100 A50,50 0 1,1 50,0 Z"; // 圆形动态生成路径
function createCirclePath(centerX, centerY, radius) {
return `M${centerX},${centerY - radius} A${radius},${radius} 0 1,1 ${centerX},${centerY + radius} A${radius},${radius} 0 1,1 ${centerX},${centerY - radius} Z`;
}
gsap.to(".box", {
motionPath: {
path: createCirclePath(100, 100, 50)
},
duration: 2
});🛠️ 高级技巧
结合 ScrollTrigger
gsap.to(".box", {
motionPath: {
path: "#path",
autoRotate: true
},
scrollTrigger: {
trigger: ".container",
start: "top top",
end: "bottom bottom",
scrub: true
}
});路径进度控制
const tl = gsap.timeline();
tl.to(".box", {
motionPath: {
path: "#path",
end: 0.5 // 只移动到路径的一半
},
duration: 1
})
.to(".box", {
motionPath: {
path: "#path",
start: 0.5,
end: 1 // 从一半到结束
},
duration: 1
});自定义路径函数
function createWavePath(amplitude, frequency, length) {
let path = "M0,0";
for (let i = 0; i <= length; i++) {
const x = i;
const y = Math.sin(i / frequency) * amplitude;
path += ` L${x},${y}`;
}
return path;
}
gsap.to(".wave", {
motionPath: {
path: createWavePath(50, 10, 200)
},
duration: 2,
repeat: -1,
ease: "none"
});💡 最佳实践
1. 优化路径复杂度
// ❌ 不推荐:过于复杂的路径
const complexPath = "M0,0 C10,10 20,20 30,30 C40,40 50,50 60,60..."; // 太多点
// ✅ 推荐:简化路径
const simplePath = "M0,0 Q50,50 100,0"; // 使用二次曲线2. 使用 autoRotate 增强真实感
// ✅ 推荐:自动旋转
motionPath: {
path: "#path",
autoRotate: true // 元素沿路径方向旋转
}3. 合理使用 ease
// 持续运动:使用 none
gsap.to(".box", {
motionPath: { path: "#path" },
ease: "none" // 匀速
});
// 加速/减速:使用缓动
gsap.to(".box", {
motionPath: { path: "#path" },
ease: "power2.inOut" // 缓入缓出
});