gsap
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGSAP — Animation Engine
GSAP — 动画引擎
When to use GSAP
何时使用GSAP
| Criteria | CSS Transitions | Framer Motion | GSAP |
|---|---|---|---|
| Hover / simple toggle | Yes | Yes | Overkill |
| Sequenced timeline | No | Limited | Yes |
| Scroll-driven | scroll-timeline | Limited | ScrollTrigger |
| Complex stagger | No | Basic | Distribution |
| Mobile perf (60fps) | Good | Average | Excellent |
| Text splitting | No | No | SplitText |
| SVG morph / draw | No | No | MorphSVG |
| Bundle size concern | 0kb | ~30kb | ~25kb + plugins |
Rule: if the animation needs timeline, scroll-link, or distributed stagger, use GSAP. Otherwise CSS first.
| 评估标准 | CSS 过渡 | Framer Motion | GSAP |
|---|---|---|---|
| 悬停/简单切换 | 适用 | 适用 | 大材小用 |
| 序列时间线 | 不适用 | 功能有限 | 适用 |
| 滚动驱动动画 | scroll-timeline | 功能有限 | ScrollTrigger |
| 复杂交错动画 | 不适用 | 基础支持 | 分布式效果 |
| 移动端性能(60fps) | 良好 | 一般 | 优秀 |
| 文本拆分 | 不支持 | 不支持 | SplitText |
| SVG变形/绘制 | 不支持 | 不支持 | MorphSVG |
| 包体积顾虑 | 0kb | ~30kb | ~25kb + 插件 |
规则:如果动画需要时间线、滚动联动或分布式交错效果,请使用GSAP。否则优先使用CSS。
Setup
配置步骤
js
// Always register plugins at the top level
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { SplitText } from "gsap/SplitText";
gsap.registerPlugin(ScrollTrigger, SplitText);React: use from the package instead of + manual cleanup.
useGSAP()@gsap/reactuseEffectjsx
import { useGSAP } from "@gsap/react";
useGSAP(() => {
gsap.to(".box", { x: 200 });
}, { scope: containerRef }); // auto-cleanup, auto-revertjs
// 始终在顶层注册插件
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { SplitText } from "gsap/SplitText";
gsap.registerPlugin(ScrollTrigger, SplitText);React环境:使用包中的替代+手动清理。
@gsap/reactuseGSAP()useEffectjsx
import { useGSAP } from "@gsap/react";
useGSAP(() => {
gsap.to(".box", { x: 200 });
}, { scope: containerRef }); // 自动清理、自动还原Core Patterns
核心模式
defaults{} to avoid repetition
使用defaults{}避免重复代码
js
const tl = gsap.timeline({
defaults: { duration: 0.8, ease: "power2.out" },
});
tl.to(".a", { y: -20 })
.to(".b", { y: -20 }, "<0.1")
.to(".c", { y: -20 }, "<0.1");js
const tl = gsap.timeline({
defaults: { duration: 0.8, ease: "power2.out" },
});
tl.to(".a", { y: -20 })
.to(".b", { y: -20 }, "<0.1")
.to(".c", { y: -20 }, "<0.1");fromTo for full control
使用fromTo实现完全控制
js
gsap.fromTo(".card", { y: 40, opacity: 0 }, { y: 0, opacity: 1, stagger: 0.15 });js
gsap.fromTo(".card", { y: 40, opacity: 0 }, { y: 0, opacity: 1, stagger: 0.15 });Stagger with distribution
带分布效果的交错动画
js
gsap.to(".grid-item", {
scale: 0,
stagger: {
each: 0.05,
from: "center", // "start" | "end" | "center" | "edges" | "random" | index
grid: "auto", // auto-detects the grid
axis: "x", // "x" | "y" | null (both)
},
});js
gsap.to(".grid-item", {
scale: 0,
stagger: {
each: 0.05,
from: "center", // "start" | "end" | "center" | "edges" | "random" | 索引
grid: "auto", // 自动检测网格布局
axis: "x", // "x" | "y" | null(同时生效)
},
});ScrollTrigger Patterns
ScrollTrigger 模式
Basic Pin + Scrub
基础固定+滚动Scrub
js
gsap.to(".panel", {
x: "-300%",
ease: "none",
scrollTrigger: {
trigger: ".container",
pin: true,
scrub: 1,
end: () => "+=" + document.querySelector(".container").scrollWidth,
},
});js
gsap.to(".panel", {
x: "-300%",
ease: "none",
scrollTrigger: {
trigger: ".container",
pin: true,
scrub: 1,
end: () => "+=" + document.querySelector(".container").scrollWidth,
},
});Batch for mass reveal
批量元素显示
js
ScrollTrigger.batch(".card", {
onEnter: (elements) => gsap.to(elements, { opacity: 1, y: 0, stagger: 0.1 }),
start: "top 85%",
});js
ScrollTrigger.batch(".card", {
onEnter: (elements) => gsap.to(elements, { opacity: 1, y: 0, stagger: 0.1 }),
start: "top 85%",
});Horizontal scroll with containerAnimation
结合containerAnimation实现水平滚动
js
const scrollTween = gsap.to(".panels", {
x: () => -(document.querySelector(".panels").scrollWidth - window.innerWidth),
ease: "none",
scrollTrigger: { trigger: ".wrapper", pin: true, scrub: 1 },
});
// Animate elements INSIDE the horizontal scroll
gsap.to(".panel-content", {
scale: 1.2,
scrollTrigger: {
trigger: ".panel-content",
containerAnimation: scrollTween, // linked to horizontal scroll
start: "left center",
end: "right center",
scrub: true,
},
});js
const scrollTween = gsap.to(".panels", {
x: () => -(document.querySelector(".panels").scrollWidth - window.innerWidth),
ease: "none",
scrollTrigger: { trigger: ".wrapper", pin: true, scrub: 1 },
});
// 在水平滚动内部动画元素
gsap.to(".panel-content", {
scale: 1.2,
scrollTrigger: {
trigger: ".panel-content",
containerAnimation: scrollTween, // 关联水平滚动
start: "left center",
end: "right center",
scrub: true,
},
});DO NOT — Critical mistakes
切勿踩坑 — 常见错误
1. Ease on containerAnimation
1. 在containerAnimation上设置缓动
js
// BAD — ease breaks the scroll mapping
scrollTrigger: { containerAnimation: scrollTween, scrub: 1, ease: "power2.out" }
// GOOD — always ease: "none" on the parent tween
const scrollTween = gsap.to(".panels", { x: ..., ease: "none", scrollTrigger: { scrub: 1 } });js
// 错误示例 — 缓动会破坏滚动映射
scrollTrigger: { containerAnimation: scrollTween, scrub: 1, ease: "power2.out" }
// 正确示例 — 父级补间始终设置ease: "none"
const scrollTween = gsap.to(".panels", { x: ..., ease: "none", scrollTrigger: { scrub: 1 } });2. ScrollTrigger on a child tween in a timeline
2. 在带ScrollTrigger的时间线子补间上添加ScrollTrigger
js
// BAD — ScrollTrigger ignores child tweens of a timeline that has its own ScrollTrigger
const tl = gsap.timeline({ scrollTrigger: { trigger: ".section" } });
tl.to(".box", { x: 100, scrollTrigger: { trigger: ".box" } }); // IGNORE
// GOOD — one ScrollTrigger per timeline OR standalone tweens
gsap.to(".box", { x: 100, scrollTrigger: { trigger: ".box" } }); // tween standalonejs
// 错误示例 — 带有自身ScrollTrigger的时间线会忽略子补间的ScrollTrigger
const tl = gsap.timeline({ scrollTrigger: { trigger: ".section" } });
tl.to(".box", { x: 100, scrollTrigger: { trigger: ".box" } }); // 被忽略
// 正确示例 — 每个时间线或独立补间仅设置一个ScrollTrigger
gsap.to(".box", { x: 100, scrollTrigger: { trigger: ".box" } }); // 独立补间3. setState in onUpdate
3. 在onUpdate中调用setState
js
// BAD — setState 60x/s = re-render hell
scrollTrigger: { onUpdate: (self) => setProgress(self.progress) }
// GOOD — mutate a ref or DOM element directly
const progressRef = useRef(0);
scrollTrigger: { onUpdate: (self) => { progressRef.current = self.progress; } }
// Or better: gsap.quickSetter to mutate the DOM without Reactjs
// 错误示例 — 每秒60次setState会导致渲染地狱
scrollTrigger: { onUpdate: (self) => setProgress(self.progress) }
// 正确示例 — 直接修改ref或DOM元素
const progressRef = useRef(0);
scrollTrigger: { onUpdate: (self) => { progressRef.current = self.progress; } }
// 更优方案:使用gsap.quickSetter直接修改DOM,无需通过React4. immediateRender on from() in a timeline
4. 时间线中from()的immediateRender属性
js
// BAD — from() has immediateRender: true by default, breaks sequencing
tl.to(".box", { x: 100 });
tl.from(".box", { y: 50 }); // visually jumps to the start
// GOOD — disable immediateRender when from() follows another tween
tl.to(".box", { x: 100 });
tl.from(".box", { y: 50, immediateRender: false });js
// 错误示例 — from()默认immediateRender: true,会破坏序列
tl.to(".box", { x: 100 });
tl.from(".box", { y: 50 }); // 视觉上会跳转到初始状态
// 正确示例 — 当from()跟随其他补间时,禁用immediateRender
tl.to(".box", { x: 100 });
tl.from(".box", { y: 50, immediateRender: false });5. Animating non-transform properties
5. 动画非transform属性
js
// BAD — width/height/top/left trigger layout reflow
gsap.to(".box", { width: 200, height: 200 });
// GOOD — use transforms (GPU-accelerated, composited)
gsap.to(".box", { scaleX: 1.5, scaleY: 1.5 });
// If actual size needed: use Flip plugin for layout transitionjs
// 错误示例 — width/height/top/left会触发布局重排
gsap.to(".box", { width: 200, height: 200 });
// 正确示例 — 使用transform(GPU加速,合成层渲染)
gsap.to(".box", { scaleX: 1.5, scaleY: 1.5 });
// 如果需要实际尺寸变化:使用Flip插件实现布局过渡Refs
参考资料
- — Complete gsap.to/from/fromTo/set API, options
references/core.md - — Timeline, position parameter, nesting
references/timeline.md - — Full ScrollTrigger reference
references/scrolltrigger.md - — SplitText, Flip, MorphSVG, DrawSVG, MotionPath, Observer
references/plugins.md
- — 完整的gsap.to/from/fromTo/set API及选项
references/core.md - — 时间线、位置参数、嵌套
references/timeline.md - — ScrollTrigger完整参考
references/scrolltrigger.md - — SplitText、Flip、MorphSVG、DrawSVG、MotionPath、Observer插件
references/plugins.md