gsap 配置解读 --3
drawSVG 是什么
<div class="card">
<h1>案例 15:DrawSVG 绘制路径</h1>
<p>DrawSVGPlugin 可以控制路径的绘制百分比。</p>
<svg viewBox="0 0 200 200">
<path id="path" class="stroke" d="M40 100 C40 40, 160 40, 160 100 C160 160, 40 160, 40 100" />
</svg>
<button id="play">绘制路径</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/DrawSVGPlugin.min.js"></script>
<script>
const path = document.querySelector("#path");
const playButton = document.querySelector("#play");
// 注册 DrawSVGPlugin
gsap.registerPlugin(DrawSVGPlugin);
// drawSVG: "0% 100%" 表示从头绘制到尾
const tween = gsap.fromTo(
path,
{ drawSVG: "0% 0%" },
{ drawSVG: "0% 100%", duration: 1.6, ease: "power2.out", paused: true }
);
playButton.addEventListener("click", () => {
tween.restart();
});
</script>
drawSVG 是 GSAP(GreenSock Animation Platform)官方提供的一个强大插件 —— DrawSVGPlugin 的核心功能,专门用于以动画方式“绘制”或“擦除” SVG 路径(<path>、<line>、<polyline>、<polygon>、<rect>、<circle> 等),实现类似“手绘”、“描边动画”的效果。
📌 你的代码解释:
gsap.fromTo(
path,
{ drawSVG: "0% 0%" }, // 起始状态:路径完全未绘制(0% 到 0%)
{ drawSVG: "0% 100%", duration: 1.6, ease: "power2.out", paused: true }
);
这段代码的作用是:
让 SVG 路径从“完全隐藏”状态,平滑地“画出来”,直到完整显示整个路径。
点击按钮后,调用 tween.restart() 重新播放这个绘制动画。
✅ drawSVG 的工作原理
SVG 路径本身是一条“线”,但默认是立即完整显示的。DrawSVGPlugin 通过动态控制 SVG 的 stroke-dasharray 和 stroke-dashoffset 属性,来只显示路径的一部分,从而模拟“绘制”过程。
-
drawSVG: "0% 0%"→ 显示 0% 到 0% → 完全隐藏 -
drawSVG: "0% 50%"→ 显示前 50% -
drawSVG: "0% 100%"→ 显示全部 → 完整路径 -
drawSVG: "100% 100%"→ 也完全隐藏(可以用来做“擦除”效果)
💡 它支持百分比(
"0% 100%")、绝对长度("0px 200px")或关键词("start","end")。
🔧 常见用法示例
1. 从头到尾绘制(你的例子)
{ drawSVG: "0% 100%" }
2. 从尾到头绘制(反向)
{ drawSVG: "100% 0%" } // 注意顺序:起始 > 结束 = 反向
3. 中间一段高亮(常用于进度指示)
{ drawSVG: "40% 60%" }
4. 擦除效果(从完整到消失)
gsap.to(path, { drawSVG: "0% 0%", duration: 1 });
5. 循环绘制 + 擦除
gsap.to(path, {
drawSVG: "0% 100%",
duration: 1,
yoyo: true,
repeat: -1
});
✅ 支持的 SVG 元素
| 元素 | 是否支持 |
|---|---|
<path> |
✅ 最常用 |
<line> |
✅ |
<polyline> |
✅ |
<polygon> |
✅ |
<rect> |
✅(需有 stroke) |
<circle> / <ellipse>
|
✅ |
<text> |
❌(不支持,但可用 textPath 包裹路径) |
⚠️ 要求元素必须有
stroke(描边),且stroke-width > 0。填充(fill)不影响绘制动画。
🎨 样式建议(CSS)
.stroke {
fill: none; /* 通常设为无填充 */
stroke: #3b82f6; /* 描边颜色 */
stroke-width: 4; /* 描边宽度 */
stroke-linecap: round;/* 线帽样式(可选)*/
}
⚠️ 注意事项
-
必须注册插件:
gsap.registerPlugin(DrawSVGPlugin); -
路径必须是“单一线条”
复杂组合路径(如多个子路径)可能表现异常,建议简化或拆分。 -
性能优秀
DrawSVGPlugin内部优化良好,即使在低端设备上也能流畅运行。 -
与 ScrollTrigger 结合极佳
常用于“滚动触发动画”:gsap.to(path, { scrollTrigger: ".section", drawSVG: "0% 100%", duration: 1 });
✅ 总结
| 术语 | 含义 |
|---|---|
drawSVG |
GSAP 的 DrawSVGPlugin 提供的属性,用于控制 SVG 路径的“绘制进度” |
| 典型值 |
"0% 0%"(隐藏)、"0% 100%"(完整绘制)、"100% 0%"(反向绘制) |
EaselPlugin是什么
<div class="card">
<h1>案例 16:EaselPlugin + Canvas</h1>
<p>用 GSAP 驱动 EaselJS 的对象属性。</p>
<canvas id="stage" width="420" height="220"></canvas>
<button id="play">播放动画</button>
</div>
<script src="https://code.createjs.com/1.0.0/easeljs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/EaselPlugin.min.js"></script>
<script>
const canvas = document.querySelector("#stage");
const playButton = document.querySelector("#play");
// 创建 EaselJS 舞台与图形
const stage = new createjs.Stage(canvas);
const circle = new createjs.Shape();
circle.graphics.beginFill("#38bdf8").drawCircle(0, 0, 26);
circle.x = 60;
circle.y = 110;
stage.addChild(circle);
stage.update();
// 注册 EaselPlugin
gsap.registerPlugin(EaselPlugin);
// GSAP 让 EaselJS 图形移动与缩放
const tween = gsap.to(circle, {
x: 360,
scaleX: 1.4,
scaleY: 1.4,
duration: 1.4,
ease: "power2.out",
paused: true
});
// 每帧刷新舞台
gsap.ticker.add(() => {
stage.update();
});
playButton.addEventListener("click", () => {
tween.restart();
});
</script>
EaselJS 是 CreateJS 套件中的一个核心库,专门用于在 HTML5 <canvas> 画布上进行高性能的 2D 图形绘制与交互开发。它提供了一套类似 Flash/ActionScript 的面向对象 API,让开发者能轻松创建、操作和动画化矢量图形、位图、文本等元素。
📌 在你的代码中,EaselJS 的作用是:
- 创建一个 Canvas 舞台(Stage)
- 绘制一个圆形(Shape)并添加到舞台上
- 通过 GSAP + EaselPlugin 控制该圆形的位置和缩放
而 EaselPlugin 是 GSAP 的一个官方插件,让 GSAP 能直接动画化 EaselJS 对象的属性(如 x, y, scaleX, rotation 等),并自动触发舞台重绘。
✅ EaselJS 核心概念
| 概念 | 说明 |
|---|---|
Stage |
代表整个 <canvas> 画布,是所有显示对象的容器 |
DisplayObject |
所有可视对象的基类(如 Shape, Bitmap, Text, Container) |
Shape |
用于绘制矢量图形(圆、矩形、路径等) |
Ticker |
EaselJS 自带的帧循环(但你的代码用的是 GSAP 的 ticker 来更新舞台) |
🔍 你的代码逐行解析
// 1. 创建 EaselJS 舞台
const stage = new createjs.Stage(canvas);
// 2. 创建一个圆形 Shape
const circle = new createjs.Shape();
circle.graphics.beginFill("#38bdf8").drawCircle(0, 0, 26); // 画一个半径26的圆
circle.x = 60;
circle.y = 110;
// 3. 将圆形添加到舞台
stage.addChild(circle);
// 4. 首次渲染(否则看不到)
stage.update();
// 5. 注册 GSAP 插件
gsap.registerPlugin(EaselPlugin);
// 6. 用 GSAP 动画化 EaselJS 对象!
const tween = gsap.to(circle, {
x: 360, // EaselJS 对象的 x 属性
scaleX: 1.4, // 缩放
scaleY: 1.4,
duration: 1.4,
ease: "power2.out",
paused: true
});
// 7. 关键:每帧刷新 Canvas!
gsap.ticker.add(() => {
stage.update(); // 告诉 EaselJS 重新绘制整个舞台
});
💡 如果没有
stage.update(),Canvas 不会更新,动画就“看不见”!
✅ 为什么需要 EaselPlugin?
- EaselJS 对象的属性(如
x,scaleX)不是直接作用于 DOM 或 CSS,而是存储在 JavaScript 对象中。 - GSAP 默认不知道如何“读取/写入”这些属性,也不知道何时需要调用
stage.update()。 -
EaselPlugin桥接了 GSAP 和 EaselJS:- 自动识别
createjs.DisplayObject - 正确设置/获取
x,y,rotation,scaleX/Y,alpha等属性 - (可选)自动调用
stage.update()(但你的代码手动用gsap.ticker控制,更灵活)
- 自动识别
🎯 EaselJS 的典型应用场景
| 场景 | 说明 |
|---|---|
| 游戏开发 | 2D 小游戏(平台跳跃、射击、解谜等) |
| 数据可视化 | 动态图表、交互式信息图 |
| 广告 Banner | HTML5 富媒体广告(替代 Flash) |
| 教育/演示动画 | 复杂交互动画、流程演示 |
| Canvas UI 组件 | 自定义控件、非 DOM 的界面 |
⚠️ 注意事项
-
性能 vs DOM
Canvas 适合大量图形或高频更新(如游戏),但不支持 SEO、无障碍访问(a11y)。简单 UI 优先用 DOM + CSS。 -
坐标系
EaselJS 使用标准 Canvas 坐标系:左上角(0,0),向右为 X+,向下为 Y+。 -
事件处理
EaselJS 支持鼠标/触摸事件(circle.on("click", handler)),但需启用:stage.enableMouseOver(10); // 启用 hover -
替代方案
现代项目也可考虑:- 纯 Canvas + requestAnimationFrame
- PixiJS(更强大,支持 WebGL)
- Three.js(3D)
- SVG + GSAP(矢量、可访问性好)
✅ 总结
| 术语 | 含义 |
|---|---|
| EaselJS | 一个基于 HTML5 Canvas 的 2D 图形库,提供类似 Flash 的开发体验 |
| EaselPlugin | GSAP 插件,让 GSAP 能无缝动画化 EaselJS 对象的属性 |
你的代码展示了 “用 GSAP 驱动 Canvas 图形动画” 的经典模式:
- EaselJS 负责 图形创建与渲染
- GSAP 负责 复杂缓动、时间控制、序列编排
-
gsap.ticker负责 每帧刷新画面
这种组合在需要精细控制 Canvas 动画时非常高效!
Flip 是什么
<div class="card">
<h1>案例 17:Flip 位置变换</h1>
<p>Flip 能把布局切换变成平滑动画。</p>
<div class="grid" id="grid">
<div class="item highlight">A</div>
<div class="item">B</div>
<div class="item">C</div>
<div class="item">D</div>
<div class="item">E</div>
<div class="item">F</div>
</div>
<button id="toggle">切换布局</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/Flip.min.js"></script>
<script>
const grid = document.querySelector("#grid");
const toggleButton = document.querySelector("#toggle");
let expanded = false;
// 注册 Flip 插件
gsap.registerPlugin(Flip);
toggleButton.addEventListener("click", () => {
const items = gsap.utils.toArray(".item");
// 记录布局状态
const state = Flip.getState(items);
// 切换布局
expanded = !expanded;
grid.style.gridTemplateColumns = expanded ? "repeat(2, 1fr)" : "repeat(3, 1fr)";
items[0].classList.toggle("highlight", expanded);
items[0].style.gridColumn = expanded ? "span 2" : "auto";
// 用 Flip 生成补间动画
Flip.from(state, {
duration: 0.8,
ease: "power2.inOut",
stagger: 0.04
});
});
</script>
Flip 是 GSAP(GreenSock Animation Platform)官方提供的一个革命性插件 —— FlipPlugin,它的名字是 "First, Last, Invert, Play" 的缩写,是一种高效实现布局变换平滑动画的技术。
🎯 核心思想:“记录变化前后的状态,自动生成中间过渡动画”
你不需要手动计算元素移动了多少像素、缩放了多少倍——
只需改变 DOM 结构或 CSS 布局(如 grid、flex、class、style),Flip 会自动检测差异并补间!
📌 你的代码解释:
// 1. 记录当前所有 .item 元素的状态(位置、尺寸等)
const state = Flip.getState(items);
// 2. 改变布局(这是“瞬间”的,没有动画)
expanded = !expanded;
grid.style.gridTemplateColumns = expanded ? "repeat(2, 1fr)" : "repeat(3, 1fr)";
items[0].classList.toggle("highlight", expanded);
items[0].style.gridColumn = expanded ? "span 2" : "auto";
// 3. 让 Flip 从“旧状态”动画到“新状态”
Flip.from(state, {
duration: 0.8,
ease: "power2.inOut",
stagger: 0.04
});
✅ 效果:点击按钮后,网格从 3 列变为 2 列,第一个 item 跨两列并高亮,其他元素平滑地移动、缩放到新位置,而不是“跳变”。
🔍 Flip 的工作原理(F.L.I.P.)
| 步骤 | 含义 | 你的代码中 |
|---|---|---|
| F - First | 记录元素变化前的位置/尺寸 | Flip.getState(items) |
| L - Last | 应用新的布局(DOM/CSS 改变) | 修改 gridTemplateColumns 和 gridColumn
|
| I - Invert | 通过 transform 将元素视觉上“倒回”到原始位置(用户看不见这一步) |
Flip 内部自动完成 |
| P - Play | 动画 transform 回到新位置,形成平滑过渡 |
Flip.from(state, {...}) |
💡 这种技术避免了强制重排(reflow),性能极高!
✅ Flip 的核心优势
| 优势 | 说明 |
|---|---|
| 零计算 | 无需手动算 x, y, width, height
|
| 自动处理复杂布局 | 支持 Grid、Flexbox、绝对定位、浮动等 |
| 高性能 | 只使用 transform 和 opacity,60fps 流畅 |
| 智能匹配元素 | 自动根据 DOM 节点或 key 属性关联前后元素 |
| 支持嵌套、增删元素 | 可配合 onEnter, onLeave 处理新增/移除项 |
🔧 常见用法扩展
1. 指定唯一 key(推荐用于动态列表)
// 给每个 item 加 data-id
<div class="item" data-flip-id="A">A</div>
// Flip 会按 data-flip-id 匹配元素
Flip.from(state, {
absolute: true, // 使用绝对定位避免布局抖动
simple: true // 简化动画(仅位移+缩放)
});
2. 处理新增/删除元素
Flip.from(state, {
onEnter: (elements) => gsap.from(elements, { opacity: 0, scale: 0 }), // 新增项淡入
onLeave: (elements) => gsap.to(elements, { opacity: 0 }) // 移除项淡出
});
3. 与 React/Vue 集成
在虚拟 DOM 更新后调用 Flip.getState() → 触发渲染 → 调用 Flip.from(),实现声明式布局动画。
⚠️ 注意事项
-
必须注册插件:
gsap.registerPlugin(Flip); -
元素需有明确尺寸和位置(避免
display: none或未渲染状态) -
默认使用相对定位,若布局跳动可加
absolute: true - 不适用于纯颜色/文本内容变化(那是 CSS Transition 的领域)
✅ 总结
| 术语 | 含义 |
|---|---|
Flip (FlipPlugin) |
GSAP 插件,通过记录布局前后状态,自动生成平滑的元素位置/尺寸变换动画 |
你的代码是一个典型的 “响应式网格布局切换” 示例,广泛应用于:
- 卡片列表 ↔ 网格视图切换
- 侧边栏展开/收起
- 动态表单布局调整
- 数据可视化重排
💡 一句话记住 Flip:
“改 CSS,记状态,自动生成动画” —— 布局动画从未如此简单!
什么是GSDevTools
<div class="card">
<h1>案例 18:GSDevTools 调试面板</h1>
<p>GSDevTools 用来调试时间线与动画进度。</p>
<div class="stage">
<div class="block" id="block"></div>
</div>
<div class="hint">页面底部会出现调试面板</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/GSDevTools.min.js"></script>
<script>
const block = document.querySelector("#block");
// 创建一个循环时间线
const timeline = gsap.timeline({ repeat: -1, yoyo: true });
timeline.to(block, { x: 460, duration: 1.4, ease: "power2.inOut" });
timeline.to(block, { rotation: 180, duration: 0.8, ease: "power2.inOut" }, 0);
// 创建调试面板
GSDevTools.create({ animation: timeline });
</script>
什么是 InertiaPlugin
<div class="card">
<h1>案例 19:Inertia 惯性拖拽</h1>
<p>松手后带惯性滑动。</p>
<div class="stage">
<div class="ball" id="ball"></div>
</div>
<div class="hint">拖动小球后快速松手</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/Draggable.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/InertiaPlugin.min.js"></script>
<script>
const ball = document.querySelector("#ball");
// 注册插件
gsap.registerPlugin(Draggable, InertiaPlugin);
// 开启惯性效果
Draggable.create(ball, {
type: "x,y",
bounds: ".stage",
inertia: true
});
</script>
就是添加这个属性 是否开启惯性 inertia: true
MotionPathPlugin是什么
<div class="card">
<h1>案例 20:MotionPath 路径运动</h1>
<p>让元素沿着 SVG 路径运动。</p>
<svg viewBox="0 0 420 220">
<path
id="track"
class="path"
d="M20 180 C120 40, 300 40, 400 180"
/>
<circle id="dot" class="dot" r="10" cx="20" cy="180"></circle>
</svg>
<button id="play">沿路径运动</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/MotionPathHelper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/MotionPathPlugin.min.js"></script>
<script>
const dot = document.querySelector("#dot");
const track = document.querySelector("#track");
const playButton = document.querySelector("#play");
// 注册 MotionPathPlugin
gsap.registerPlugin(MotionPathPlugin);
const tween = gsap.to(dot, {
duration: 1.8,
ease: "power1.inOut",
motionPath: {
path: track,
align: track,
alignOrigin: [0.5, 0.5]
},
paused: true
});
playButton.addEventListener("click", () => {
tween.restart();
});
</script>
motionPath 是 GSAP(GreenSock Animation Platform) 动画库中的一个强大功能,由 MotionPathPlugin 插件提供,用于让元素沿着指定的 路径(path) 进行动画运动。
📌 简单定义:
motionPath允许你将一个 DOM 元素(如<div>、<circle>等)沿着 SVG 路径(<path>、<circle>、<rect>等)或一组坐标点进行平滑移动,并可自动旋转以对齐路径方向。
✅ 核心特性:
-
路径支持多种格式:
- SVG 的
<path>元素(最常用) - 其他 SVG 形状(如
<circle>,<rect>,<polygon>) - 一组
{x, y}坐标点组成的数组 - 字符串形式的 SVG 路径数据(d 属性)
- SVG 的
-
自动对齐(align):
- 可通过
align: path让元素在移动时朝向路径切线方向(比如让飞机头始终指向飞行方向)。 -
alignOrigin控制对齐的“锚点”,例如[0.5, 0.5]表示元素中心对齐。
- 可通过
-
精确控制:
- 支持
start和end属性,控制沿路径的起止位置(0 到 1)。 - 可结合 GSAP 的时间轴、缓动函数(ease)、重复等高级功能。
- 支持
gsap.to(dot, {
duration: 1.8,
ease: "power1.inOut",
motionPath: {
path: track, // 沿着 #track 这个 SVG 路径移动
align: track, // 元素方向对齐路径
alignOrigin: [0.5, 0.5] // 以圆点中心为对齐基准
},
paused: true
});
-
#dot(一个小圆)会从路径起点(20,180)开始, - 沿着贝塞尔曲线
M20 180 C120 40, 300 40, 400 180移动到终点(400,180), - 移动过程中,由于设置了
align,它会自动旋转以匹配路径的走向(虽然圆形看不出旋转,但如果是箭头就很明显)。
💡 注:圆形 (
<circle>) 本身没有方向感,所以align效果不明显。若换成<use>引用一个飞机图标,就能看到“朝向路径”的效果。
🌟 应用场景:
- 游戏角色沿轨道移动
- 数据可视化中的动态轨迹
- 引导式 UI 动画(如教程提示沿路径走)
- 创意交互动画(如文字沿曲线飞入)
📚 官方文档:
总结:motionPath 是 GSAP 中实现“路径动画”的核心工具,让复杂轨迹运动变得简单、流畅且高度可控。