关于 gsap-plugins
gsap-plugins 是帮助开发者使用和审查 GSAP 插件的技能,涵盖插件注册、配置与常见交互动画。内容还说明通过公开的 gsap npm 包安装插件及其当前许可信息。
主要功能
- 01介绍 GSAP 插件注册方式
- 02涵盖滚动、拖拽与惯性插件
- 03使用 Flip 动画切换布局状态
- 04用 SplitText 和 ScrambleText 制作文字效果
- 05说明插件安装与许可信息
适用场景
- 01实现滚动到目标位置的动画
- 02构建可拖动或带惯性的界面元素
- 03制作文字拆分、揭示或扰乱效果
- 04在列表或网格状态变化时添加过渡
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nexu-io/ open-design --skill gsap-plugins安装后在 Claude Code 中输入/gsap-plugins确认已加载。
附带文件LICENSESOURCES.md
详细介绍
GSAP 插件
整理自 GreenSock 官方 GSAP 技能:https://github.com/greensock/gsap-skills
何时使用此技能
在使用或审查使用 GSAP 插件的代码时使用:注册插件、滚动到指定位置、翻转/FLIP 动画、可拖动元素、SVG(DrawSVG、MorphSVG、MotionPath)、文本(SplitText、ScrambleText)、物理效果、缓动插件(CustomEase、EasePack、CustomWiggle、CustomBounce)或 GSDevTools。ScrollTrigger 有单独的技能(gsap-scrolltrigger)。
**相关技能:**核心补间动画请使用 gsap-core;ScrollTrigger 请使用 gsap-scrolltrigger;React 请使用 gsap-react。
许可与安装(重要)
所有 GSAP 插件均免费,包括商业用途。自 Webflow 收购 GSAP 后,Club GSAP 不再是付费等级,任何插件都不需要会员资格、许可证密钥或身份验证令牌——这也包括以前仅限 Club 使用的插件(SplitText、MorphSVG 等)。
- ✅ 从公开的
gsapnpm 包安装所有内容:npm install gsap。其中包含所有插件——例如,可将它们导入为gsap/SplitText、gsap/MorphSVGPlugin等。 - ❌ 不要生成包含 GreenSock 身份验证令牌的
.npmrc,不要建议使用私有的npm.greensock.com注册表,也不要告诉用户注册 Club GSAP 才能使用插件。这些说明已经过时。
注册插件
注册每个插件一次,以便 GSAP(和打包工具)知道要将其包含在内。对项目中使用的每个插件调用 gsap.registerPlugin():
import gsap from "gsap";
import { ScrollToPlugin } from "gsap/ScrollToPlugin";
import { Flip } from "gsap/Flip";
import { Draggable } from "gsap/Draggable";
gsap.registerPlugin(ScrollToPlugin, Flip, Draggable);
- ✅ 在补间动画或 API 调用中使用插件之前先注册。
- ✅ 在 React 中,在顶层或应用中注册一次(例如,在首次调用 useGSAP 之前);不要在会重新渲染的组件内注册。useGSAP 是一个需要先注册才能使用的插件。
滚动
ScrollToPlugin
为滚动位置(窗口或可滚动元素)添加动画。无需使用 ScrollTrigger,即可实现“滚动到元素”或“滚动到指定位置”。
gsap.registerPlugin(ScrollToPlugin);
gsap.to(window, { duration: 1, scrollTo: { y: 500 } });
gsap.to(window, { duration: 1, scrollTo: { y: "#section", offsetY: 50 } });
gsap.to(scrollContainer, { duration: 1, scrollTo: { x: "max" } });
ScrollToPlugin — 关键配置(scrollTo 对象):
| 选项 | 说明 |
|---|---|
x、y | 目标滚动位置(数字),或使用 "max" 表示最大值 |
element | 要滚动到的选择器或元素(用于滚动到视图中) |
offsetX、offsetY | 相对于目标位置的偏移量(像素) |
ScrollSmoother
平滑滚动包装器(使原生滚动更加平滑)。需要 ScrollTrigger 和特定的 DOM 结构(内容包装器 + 平滑包装器)。需要平滑、具有惯性的滚动效果时使用。设置方法请参阅 GSAP 文档;在 ScrollTrigger 之后注册。DOM 结构如下所示:
<body>
<div id="smooth-wrapper">
<div id="smooth-content">
</div>
</div>
</body>
DOM / UI
Flip
使用 Flip.getState() 捕获状态,然后应用更改(例如布局或类名更改),再使用 Flip.from() 从之前的状态动画到新状态(FLIP:First、Last、Invert、Play)。适用于在两种布局状态之间添加动画(列表、网格、展开/折叠)。
gsap.registerPlugin(Flip);
const state = Flip.getState(".item");
// change DOM (reorder, add/remove, change classes)
Flip.from(state, { duration: 0.5, ease: "power2.inOut" });
Flip — 关键配置(Flip.from vars):
| 选项 | 说明 |
|---|---|
absolute | 翻转期间使用 position: absolute(默认值:false) |
nested | 为 true 时,仅测量第一层子元素(更适合嵌套变换) |
scale | 为 true 时,缩放元素以适应空间(避免拉伸);默认值为 true |
simple | 为 true 时,仅为位置/缩放添加动画(速度更快,但精度较低) |
duration、ease | 标准补间动画选项 |
更多信息
https://gsap.com/docs/v3/Plugins/Flip
Draggable
通过鼠标或触控,让元素可拖动、旋转或投掷。适用于滑块、卡片、可重新排序的列表或任何拖动交互。
gsap.registerPlugin(Draggable, InertiaPlugin);
Draggable.create(".box", { type: "x,y", bounds: "#container", inertia: true });
Draggable.create(".knob", { type: "rotation" });
Draggable — 关键配置选项:
| 选项 | 说明 |
|---|---|
type | "x"、"y"、"x,y"、"rotation"、"scroll" |
bounds | 用于限制拖动范围的元素、选择器或 { minX, maxX, minY, maxY } |
inertia | 设为 true 可启用投掷/惯性效果(需要 InertiaPlugin) |
edgeResistance | 0–1;拖动超出边界时的阻力 |
cursor | 拖动期间的 CSS 光标 |
onDragStart、onDrag、onDragEnd | 回调;接收事件和目标 |
onThrowUpdate、onThrowComplete | 惯性效果启用时调用的回调 |
Inertia(InertiaPlugin)
与 Draggable 配合使用,可在松开后产生惯性;也可追踪任意对象任意属性的惯性/速度,然后通过简单的补间动画让其平滑滑行至停止。使用 inertia: true 时,请与 Draggable 一起注册:
gsap.registerPlugin(Draggable, InertiaPlugin);
Draggable.create(".box", { type: "x,y", inertia: true });
或者追踪某个属性的速度:
InertiaPlugin.track(".box", "x");
然后使用 "auto" 延续当前速度,并平滑滑行至停止:
gsap.to(obj, { inertia: { x: "auto" } });
Observer
在不同设备间规范化指针和滚动输入。可用于滑动、滚动方向检测或自定义手势逻辑,无需像 ScrollTrigger 那样直接绑定滚动位置。
gsap.registerPlugin(Observer);
Observer.create({
target: "#area",
onUp: () => {},
onDown: () => {},
onLeft: () => {},
onRight: () => {},
tolerance: 10
});
Observer — 关键配置选项:
| 选项 | 说明 |
|---|---|
target | 要观察的元素或选择器 |
onUp、onDown、onLeft、onRight | 滑动/滚动在相应方向超过容差时调用的回调 |
tolerance | 检测方向前需移动的像素数;默认值为 10 |
type | "touch"、"pointer" 或 "wheel"(默认值:"touch,pointer") |
文本
SplitText
将元素文本拆分为字符、单词和/或行(每个单位各自放在独立元素中),以便进行错开动画或逐单位动画。适用于逐字符、逐单词或逐行制作文本动画。返回一个实例,其中包含 chars、words、lines(设置 mask 时还包含 masks)。使用 revert() 恢复原始标记,或由 gsap.context() 还原。可与 gsap.context()、matchMedia() 和 useGSAP() 集成。API:SplitText.create(target, vars)(target = 选择器、元素或数组)。
gsap.registerPlugin(SplitText);
const split = SplitText.create(".heading", { type: "words, chars" });
gsap.from(split.chars, { opacity: 0, y: 20, stagger: 0.03, duration: 0.4 });
// later: split.revert() or let gsap.context() cleanup revert
使用 onSplit()(v3.13.0+)时,每次拆分以及使用 autoSplit 重新拆分时都会运行动画;从 onSplit() 返回补间动画/时间轴,可让 SplitText 在重新拆分时清理并同步进度:
SplitText.create(".split", {
type: "lines",
autoSplit: true,
onSplit(self) {
return gsap.from(self.lines, { y: 100, opacity: 0, stagger: 0.05, duration: 0.5 });
}
});
SplitText — 关键配置(SplitText.create vars):
| 选项 | 说明 |
|---|---|
| type | 逗号分隔的值:"chars"、"words"、"lines"。默认值为 "chars,words,lines"。为提升性能,只拆分需要的内容(例如,不拆分行时使用 "words, chars")。避免只按字符拆分而不拆分单词或行;或者使用 smartWrap: true,防止出现奇怪的换行。 |
| charsClass、wordsClass、linesClass | 应用于每个拆分元素的 CSS 类。追加 "++" 可添加递增的类名(例如,linesClass: "line++" → line1、line2,……)。 |
| aria | "auto"(默认值)、"hidden" 或 "none"。无障碍访问:"auto" 会在拆分元素上添加 aria-label,并在行、单词和字符元素上添加 aria-hidden,以便屏幕阅读器读取标签;"hidden" 会对屏幕阅读器隐藏所有内容;"none" 不更改 aria 属性。如果需要公开嵌套链接或语义,请将其设为 "none",并添加仅供屏幕阅读器使用的重复内容。 |
| autoSplit | 为 true 时,在字体加载完成或元素宽度发生变化时(且拆分了行),会还原并重新拆分,避免错误换行。必须在 onSplit() 内创建动画,这样动画才能作用于新拆分的元素;从 onSplit() 返回动画,以便在重新拆分时自动清理动画并同步时间。 |
| onSplit(self) | 拆分完成时调用的回调(若 autoSplit 为 true,每次重新拆分时也会调用)。会接收 SplitText 实例。返回 GSAP 补间或时间轴,可在重新拆分时自动还原或同步该动画。 |
| mask | "lines"、"words" 或 "chars"。会将每个单元包裹在额外元素中,并设置 overflow: clip,以实现遮罩/显示效果。只能使用一种类型;可通过实例的 masks 数组访问包装元素(或者在设置了类名时使用 -mask 类)。 |
| tag | 包装元素的标签;默认值为 "div"。行内内容请使用 "span"(注意:在某些浏览器中,旋转/缩放等变换可能无法应用于行内元素)。 |
| deepSlice | 为 true(默认值)时,会拆分跨越多行的嵌套元素(例如 <strong>),避免行在垂直方向上拉伸。仅在拆分行时生效。 |
| ignore | 保持不拆分的选择器或元素(例如,ignore: "sup")。 |
| smartWrap | 仅按字符拆分时,会将单词包裹在 white-space: nowrap 的 span 中,避免单词从中间换行。拆分单词或行时会忽略此选项。默认值为 false。 |
| wordDelimiter | 单词边界:字符串(默认值为 " ")、RegExp,或 { delimiter: RegExp, replaceWith: string },用于自定义拆分(例如,为标签或非拉丁文字使用零宽连接符)。 |
| prepareText(text, parent) | 接收原始文本和父元素的函数;拆分前返回修改后的文本(例如,为不使用空格的语言插入换行标记)。 |
| propIndex | 为 true 时,会在每个拆分元素上添加带索引的 CSS 变量(例如,--word: 1、--char: 2)。 |
| reduceWhiteSpace | 合并连续空格;默认值为 true。从 v3.13.0 起,也会保留换行,并可为 <pre> 插入 <br>。 |
| onRevert | 实例还原时调用的回调。 |
提示: 只拆分要制作动画的内容(例如,只为单词制作动画时跳过字符拆分)。对于自定义字体,请在字体加载后再拆分(例如,使用 document.fonts.ready.then(...)),或者使用 autoSplit: true 和 onSplit()。为避免拆分字符时出现字距偏移,请使用 CSS font-kerning: none; text-rendering: optimizeSpeed;。避免使用 text-wrap: balance,因为它可能干扰拆分。SplitText 不支持 SVG <text>。
了解更多: SplitText
ScrambleText
使用乱码/故障效果制作文本动画。适用于以乱码效果显示或转换文本的场景。
gsap.registerPlugin(ScrambleTextPlugin);
gsap.to(".text", {
duration: 1,
scrambleText: { text: "New message", chars: "01", revealDelay: 0.5 }
});
SVG
DrawSVG(DrawSVGPlugin)
通过动画处理 stroke-dashoffset / stroke-dasharray,显示或隐藏 SVG 元素的描边。适用于 <path>、<line>、<polyline>、<polygon>、<rect>、<ellipse>。用于“绘制”或“擦除”描边。
drawSVG 值: 描述沿路径的描边可见线段(起始和结束位置),而非“随时间从 A 动画到 B”。格式为百分比或长度形式的 "start end"。示例:"0% 100%" = 完整描边;"20% 80%" = 仅显示 20% 到 80% 之间的描边(两端有间隙)。补间动画会将元素的当前线段动画到目标线段——例如,gsap.to("#path", { drawSVG: "0% 100%" }) 会从当前状态变为完整描边。单个值(例如 0、"100%")表示起点为 0:"100%" 等同于 "0% 100%"。
必需条件: 元素必须有可见描边——在 CSS 或 SVG 属性中设置 stroke 和 stroke-width;否则不会绘制任何内容。
gsap.registerPlugin(DrawSVGPlugin);
// draw from nothing to full stroke
gsap.from("#path", { duration: 1, drawSVG: 0 });
// or explicit segment: from 0–0 to 0–100%
gsap.fromTo("#path", { drawSVG: "0% 0%" }, { drawSVG: "0% 100%", duration: 1 });
// stroke only in the middle (gaps at ends)
gsap.to("#path", { duration: 1, drawSVG: "20% 80%" });
注意事项: 仅影响描边(不影响填充)。建议使用单线段 <path> 元素;多线段路径在某些浏览器中可能会出现渲染异常。无法直观更改 <use> 的内容。DrawSVGPlugin.getLength(element) 和 DrawSVGPlugin.getPosition(element) 会返回描边长度和当前位置。
了解更多: DrawSVG
MorphSVG(MorphSVGPlugin)
通过动画处理 d 属性(路径数据),将一个 SVG 形状变形为另一个形状。起始形状和结束形状不必有相同数量的点;MorphSVG 会将其转换为三次贝塞尔曲线,并按需添加点。可用于图标间变形、形状过渡或基于路径的动画。适用于 <path>、<polyline> 和 <polygon>;<circle>、<rect>、<ellipse> 和 <line> 会在内部转换,也可以通过 MorphSVGPlugin.convertToPath(selector | element) 转换(在 DOM 中将该元素替换为 <path>)。
morphSVG 值:可以是选择器(例如 "#lightning")、元素、原始路径数据(例如 "M47.1,0.8 73.3,0.8..."),对于 polygon/polyline,也可以是 points 字符串(例如 "240,220 240,70 70,70 70,220")。要使用完整配置,请采用对象形式,其中 shape 是唯一必填属性。
gsap.registerPlugin(MorphSVGPlugin);
// convert primitives to path first if needed:
MorphSVGPlugin.convertToPath("circle, rect, ellipse, line");
gsap.to("#diamond", { duration: 1, morphSVG: "#lightning", ease: "power2.inOut" });
// object form:
gsap.to("#diamond", {
duration: 1,
morphSVG: { shape: "#lightning", type: "rotational", shapeIndex: 2 }
});
MorphSVG — 关键配置(morphSVG 对象):
| 选项 | 说明 |
|---|---|
| shape | _(必填。)_目标形状:选择器、元素或原始路径字符串。 |
| type | "linear"(默认)或 "rotational"。rotational 使用角度/长度插值,可避免变形过程中的拐折;如果 linear 效果不佳,可以尝试此选项。 |
| map | 片段的匹配方式:"size"(默认)、"position" 或 "complexity"。当起始和结束片段无法对齐时使用;如果这些方式都不适用,可将形状拆分为多条路径并分别进行变形。 |
| shapeIndex | 指定起始路径上的哪个点与结束路径上的第一个点对应(避免形状“交叉”或反转)。单片段路径使用数字;多片段路径使用数组(例如 [5, 1, -8])。负数会反转对应片段。使用一次 shapeIndex: "log" 记录自动计算的值,然后将该数字/数组粘贴到补间中。findShapeIndex(start, end)(独立工具)提供交互式 UI,可用于查找合适的值。仅适用于闭合路径。 |
| smooth | (v3.14+)。添加平滑点。可以是数字(例如 80)、"auto",或对象:{ points: 40 | "auto", redraw: true | false, persist: true | false }。redraw: false 会保留原始锚点(精度完美,但间距较不均匀)。persist: false 会在补间结束时移除添加的点。当默认变形效果显得锯齿或不自然时使用。 |
| curveMode | 布尔值(v3.14+)。插值控制柄的角度/长度,而不是原始 x/y 值,以避免曲线出现拐折。如果变形过程中出现拐折,可以尝试此选项。 |
| origin | type: "rotational" 的旋转原点。字符串:"50% 50%"(默认),或为起始和结束指定不同原点的 "20% 60%, 35% 90%"。 |
| precision | 输出路径数据的小数位数;默认值为 2。 |
| precompile | 预计算的路径字符串数组(或使用一次 precompile: "log",然后从控制台复制)。跳过耗时的启动计算;适用于非常复杂的变形。仅适用于 <path>(请先转换 polygon/polyline)。 |
| render | 每次更新时调用的函数 rawPath, target — 例如绘制到画布。RawPath 是一个片段数组(每个片段都是由三次贝塞尔曲线坐标 x、y 交替组成的数组)。 |
| updateTarget | 使用 render 时(例如仅用于 canvas),设置 updateTarget: false,以免更新原始 <path>。MorphSVGPlugin.defaultUpdateTarget 用于设置默认值。 |
**实用工具:**MorphSVGPlugin.convertToPath(selector | element) 会在 DOM 中将 circle/rect/ellipse/line/polygon/polyline 转换为 <path>。MorphSVGPlugin.rawPathToString(rawPath) 和 stringToRawPath(d) 可在路径字符串与原始数组之间进行转换。插件会在目标元素上存储原始 d(例如,变形回原形时使用:morphSVG: "#originalId" 或同一个元素)。
**提示:**如果变形出现扭曲或反转,请设置 shapeIndex(使用 "log" 或 findShapeIndex())。对于多片段路径,shapeIndex 是一个数组(每个片段对应一个值)。只有在首帧较慢时才使用 precompile;它无法修复补间期间的卡顿(如有需要,请简化 SVG 或减小尺寸)。
了解更多:MorphSVG
MotionPath (MotionPathPlugin)
让元素沿 SVG 路径运动。适用于让对象沿路径移动(例如曲线或自定义路线)。
gsap.registerPlugin(MotionPathPlugin);
gsap.to(".dot", {
duration: 2,
motionPath: { path: "#path", align: "#path", alignOrigin: [0.5, 0.5] }
});
MotionPath — 关键配置(motionPath 对象):
| 选项 | 描述 |
|---|---|
path | SVG 路径元素、选择器或路径数据字符串 |
align | 用于对齐目标的路径元素或选择器 |
alignOrigin | [x, y] 原点(0–1);默认值为 [0.5, 0.5] |
autoRotate | 旋转元素,使其沿路径切线方向移动 |
curviness | 0–2;路径平滑度 |
MotionPathHelper
MotionPath 的可视化编辑器(用于对齐、偏移)。开发期间可用于调整路径对齐。
gsap.registerPlugin(MotionPathPlugin, MotionPathHelperPlugin);
const helper = MotionPathHelper.create(".dot", "#path", { end: 0.5 });
// adjust in UI, then use helper.path or helper.getProgress() in your animation
缓动
CustomEase
自定义缓动曲线(三次贝塞尔曲线或 SVG 路径)。内置缓动无法满足需求时使用。基本用法请参阅 gsap-core;使用时需注册:
gsap.registerPlugin(CustomEase);
const ease = CustomEase.create("name", ".17,.67,.83,.67");
gsap.to(".el", { x: 100, ease: ease, duration: 1 });
EasePack
添加更多命名缓动(例如 SlowMo、RoughEase、ExpoScaleEase)。在补间动画中注册并使用这些缓动名称。
CustomWiggle
摇摆/抖动缓动。值需要“摇摆”(多次振荡)时使用。
CustomBounce
可配置强度的弹跳式缓动。
物理
Physics2D (Physics2DPlugin)
2D 物理效果(速度、角度、重力)。适用于使用简单物理效果制作动画(例如抛射物、弹跳)。
gsap.registerPlugin(Physics2DPlugin);
gsap.to(".ball", {
duration: 2,
physics2D: {
velocity: 250,
angle: 80,
gravity: 500
}
});
PhysicsProps (PhysicsPropsPlugin)
将物理效果应用于属性值。适用于由物理效果驱动的属性动画。
gsap.registerPlugin(PhysicsPropsPlugin);
gsap.to(".obj", {
duration: 2,
physicsProps: {
x: { velocity: 100, end: 300 },
y: { velocity: -50, acceleration: 200 }
}
});
开发
GSDevTools
用于拖动时间轴播放进度、切换动画和调试的 UI。仅限开发期间使用;不要随产品发布。注册后,通过时间轴引用创建实例。
gsap.registerPlugin(GSDevTools);
GSDevTools.create({ animation: tl });
其他
Pixi (PixiPlugin)
将 GSAP 与 PixiJS 集成,以便为 Pixi 显示对象制作动画。使用 GSAP 为 Pixi 对象制作动画时需注册。
gsap.registerPlugin(PixiPlugin);
const sprite = new PIXI.Sprite(texture);
gsap.to(sprite, { pixi: { x: 200, y: 100, scale: 1.5 }, duration: 1 });
最佳实践
- ✅ 首次使用前,使用 gsap.registerPlugin() 注册每个要用到的插件。
- ✅ 对于布局过渡,使用 Flip.getState() → DOM 变更 → Flip.from();对于带惯性的拖动,使用 Draggable + InertiaPlugin。
- ✅ 组件卸载或元素移除时,撤销插件实例(例如
SplitTextInstance.revert())。
请勿
- ❌ 未先注册插件(gsap.registerPlugin()),就将其用于补间动画或 API。
- ❌ 将 GSDevTools 或仅用于开发的插件随产品发布到生产环境。