elite-gsap
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseElite GSAP
高端GSAP指南
The most powerful animation library for the web. All plugins now 100% free.
目前功能最强大的网页动画库。所有插件现已100%免费。
2026 Update: GSAP is Free
2026更新:GSAP全面免费
As of Webflow's acquisition, all GSAP plugins (including former "Club" plugins) are completely free for commercial use:
- ScrollTrigger
- SplitText
- Flip
- MorphSVG
- DrawSVG
- MotionPathPlugin
- Physics2D
- Inertia
- CustomEase
No more licensing restrictions.
自Webflow收购GSAP后,所有GSAP插件(包括原"Club"专属插件)均可免费用于商业用途:
- ScrollTrigger
- SplitText
- Flip
- MorphSVG
- DrawSVG
- MotionPathPlugin
- Physics2D
- Inertia
- CustomEase
不再有任何许可限制。
Quick Reference
快速参考
| Topic | Reference File |
|---|---|
| ScrollTrigger | scrolltrigger.md |
| SplitText | splittext.md |
| Flip plugin | flip-plugin.md |
| MorphSVG & DrawSVG | morphsvg-drawsvg.md |
| Timelines | timelines.md |
| Framework integration | framework-integration.md |
| 主题 | 参考文档 |
|---|---|
| ScrollTrigger | scrolltrigger.md |
| SplitText | splittext.md |
| Flip插件 | flip-plugin.md |
| MorphSVG & DrawSVG | morphsvg-drawsvg.md |
| 时间轴 | timelines.md |
| 框架集成 | framework-integration.md |
Core Setup
核心配置
Installation
安装
bash
npm install gsapbash
npm install gsapPlugin Registration
插件注册
Register plugins once at app entry point:
javascript
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { SplitText } from 'gsap/SplitText';
import { Flip } from 'gsap/Flip';
import { DrawSVGPlugin } from 'gsap/DrawSVGPlugin';
import { MorphSVGPlugin } from 'gsap/MorphSVGPlugin';
import { MotionPathPlugin } from 'gsap/MotionPathPlugin';
gsap.registerPlugin(
ScrollTrigger,
SplitText,
Flip,
DrawSVGPlugin,
MorphSVGPlugin,
MotionPathPlugin
);在应用入口处一次性注册所需插件:
javascript
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { SplitText } from 'gsap/SplitText';
import { Flip } from 'gsap/Flip';
import { DrawSVGPlugin } from 'gsap/DrawSVGPlugin';
import { MorphSVGPlugin } from 'gsap/MorphSVGPlugin';
import { MotionPathPlugin } from 'gsap/MotionPathPlugin';
gsap.registerPlugin(
ScrollTrigger,
SplitText,
Flip,
DrawSVGPlugin,
MorphSVGPlugin,
MotionPathPlugin
);Context & Cleanup (CRITICAL)
上下文与资源清理(至关重要)
Always use to scope animations. This prevents memory leaks in SPAs and component-based frameworks.
gsap.context()**务必使用**来限定动画作用域。这可以防止单页应用(SPA)和组件化框架中出现内存泄漏问题。
gsap.context()Vanilla JS
原生JS示例
javascript
// Create context scoped to a container
const ctx = gsap.context(() => {
// All animations and ScrollTriggers created here
// are automatically tracked
gsap.from('.hero-title', { opacity: 0, y: 50 });
gsap.from('.hero-description', { opacity: 0, y: 30, delay: 0.3 });
ScrollTrigger.create({
trigger: '.section',
start: 'top center',
onEnter: () => console.log('entered')
});
}, containerElement); // Scope to container
// Later: Clean up everything
ctx.revert(); // Reverts all animations and kills ScrollTriggersjavascript
// 创建限定在容器内的上下文
const ctx = gsap.context(() => {
// 在此创建的所有动画和ScrollTrigger都会被自动追踪
gsap.from('.hero-title', { opacity: 0, y: 50 });
gsap.from('.hero-description', { opacity: 0, y: 30, delay: 0.3 });
ScrollTrigger.create({
trigger: '.section',
start: 'top center',
onEnter: () => console.log('进入可视区域')
});
}, containerElement); // 限定作用域到指定容器
// 后续清理:
ctx.revert(); // 还原所有动画并销毁ScrollTriggerWhy This Matters
为什么这很重要
Without context:
- Animations persist after component unmount
- ScrollTriggers keep listening to removed elements
- Memory leaks accumulate
- SPA navigation breaks animations
With context:
- Single call cleans everything
revert() - Safe for React/Vue/Svelte components
- No stale references
不使用上下文的问题:
- 组件卸载后动画仍会持续运行
- ScrollTrigger会继续监听已移除的元素
- 内存泄漏不断累积
- SPA导航会导致动画异常
使用上下文的优势:
- 单次调用即可清理所有资源
revert() - 适用于React/Vue/Svelte等组件框架
- 不会出现无效引用
Essential Animation Patterns
核心动画模式
Basic Tween
基础补间动画
javascript
// Animate TO a state
gsap.to('.element', {
x: 100,
opacity: 0.5,
duration: 1,
ease: 'power2.out'
});
// Animate FROM a state
gsap.from('.element', {
opacity: 0,
y: 50,
duration: 0.8,
ease: 'power3.out'
});
// FROM-TO for full control
gsap.fromTo('.element',
{ opacity: 0, y: 50 },
{ opacity: 1, y: 0, duration: 0.8 }
);
// Set immediately (no animation)
gsap.set('.element', { opacity: 1, y: 0 });javascript
// 动画到目标状态
gsap.to('.element', {
x: 100,
opacity: 0.5,
duration: 1,
ease: 'power2.out'
});
// 从指定状态开始动画
gsap.from('.element', {
opacity: 0,
y: 50,
duration: 0.8,
ease: 'power3.out'
});
// FROM-TO模式实现完全控制
gsap.fromTo('.element',
{ opacity: 0, y: 50 },
{ opacity: 1, y: 0, duration: 0.8 }
);
// 立即设置状态(无动画)
gsap.set('.element', { opacity: 1, y: 0 });Stagger Animations
stagger序列动画
javascript
// Basic stagger
gsap.from('.card', {
opacity: 0,
y: 30,
duration: 0.6,
stagger: 0.1 // 100ms between each
});
// Advanced stagger
gsap.from('.grid-item', {
opacity: 0,
scale: 0.8,
duration: 0.5,
stagger: {
each: 0.1,
from: 'center', // 'start', 'end', 'center', 'edges', 'random', or index
grid: [4, 6], // For grid layouts
axis: 'x' // 'x', 'y', or null for both
}
});javascript
// 基础序列动画
gsap.from('.card', {
opacity: 0,
y: 30,
duration: 0.6,
stagger: 0.1 // 每个元素间隔100ms
});
// 高级序列动画
gsap.from('.grid-item', {
opacity: 0,
scale: 0.8,
duration: 0.5,
stagger: {
each: 0.1,
from: 'center', // 可选值:'start', 'end', 'center', 'edges', 'random' 或索引值
grid: [4, 6], // 适配网格布局
axis: 'x' // 可选值:'x', 'y' 或null(同时作用于双轴)
}
});Easing
缓动函数
javascript
// Power eases (most common)
gsap.to('.el', { x: 100, ease: 'power1.out' }); // Subtle
gsap.to('.el', { x: 100, ease: 'power2.out' }); // Balanced (recommended)
gsap.to('.el', { x: 100, ease: 'power3.out' }); // Snappy
gsap.to('.el', { x: 100, ease: 'power4.out' }); // Dramatic
// Ease directions
// .in - starts slow, accelerates
// .out - starts fast, decelerates (default)
// .inOut - slow at both ends
// Special eases
gsap.to('.el', { x: 100, ease: 'elastic.out(1, 0.3)' });
gsap.to('.el', { x: 100, ease: 'back.out(1.7)' });
gsap.to('.el', { x: 100, ease: 'bounce.out' });
// Custom ease
gsap.to('.el', { x: 100, ease: 'M0,0 C0.7,0 0.3,1 1,1' }); // Bezierjavascript
// Power系列缓动(最常用)
gsap.to('.el', { x: 100, ease: 'power1.out' }); // 平缓
gsap.to('.el', { x: 100, ease: 'power2.out' }); // 均衡(推荐)
gsap.to('.el', { x: 100, ease: 'power3.out' }); // 灵动
gsap.to('.el', { x: 100, ease: 'power4.out' }); // 夸张
// 缓动方向
// .in - 慢启动,加速
// .out - 快启动,减速(默认)
// .inOut - 两端慢
// 特殊缓动
gsap.to('.el', { x: 100, ease: 'elastic.out(1, 0.3)' });
gsap.to('.el', { x: 100, ease: 'back.out(1.7)' });
gsap.to('.el', { x: 100, ease: 'bounce.out' });
// 自定义缓动(贝塞尔曲线)
gsap.to('.el', { x: 100, ease: 'M0,0 C0.7,0 0.3,1 1,1' });Callbacks
回调函数
javascript
gsap.to('.element', {
x: 100,
duration: 1,
onStart: () => console.log('Animation started'),
onUpdate: () => console.log('Frame update'),
onComplete: () => console.log('Animation complete'),
onReverseComplete: () => console.log('Reversed to start')
});javascript
gsap.to('.element', {
x: 100,
duration: 1,
onStart: () => console.log('动画开始'),
onUpdate: () => console.log('帧更新'),
onComplete: () => console.log('动画完成'),
onReverseComplete: () => console.log('动画反向完成')
});prefers-reduced-motion (CRITICAL)
prefers-reduced-motion(至关重要)
Always respect user motion preferences:
javascript
const mm = gsap.matchMedia();
mm.add('(prefers-reduced-motion: no-preference)', () => {
// Full animations
gsap.from('.hero', {
opacity: 0,
y: 50,
duration: 1,
ease: 'power3.out'
});
});
mm.add('(prefers-reduced-motion: reduce)', () => {
// Instant or simple fade
gsap.set('.hero', { opacity: 1, y: 0 });
// Or: gsap.from('.hero', { opacity: 0, duration: 0.3 });
});See elite-accessibility skill for comprehensive patterns.
务必尊重用户的动画偏好设置:
javascript
const mm = gsap.matchMedia();
mm.add('(prefers-reduced-motion: no-preference)', () => {
// 完整动画效果
gsap.from('.hero', {
opacity: 0,
y: 50,
duration: 1,
ease: 'power3.out'
});
});
mm.add('(prefers-reduced-motion: reduce)', () => {
// 立即显示或简单淡入
gsap.set('.hero', { opacity: 1, y: 0 });
// 或者:gsap.from('.hero', { opacity: 0, duration: 0.3 });
});如需全面的无障碍设计模式,请参考elite-accessibility技能文档。
GPU-Accelerated Properties
GPU加速属性
For 60fps performance, only animate:
- ,
x(translateX, translateY)y - ,
xPercentyPercent - ,
scale,scaleXscaleY - ,
rotation,rotationXrotationY opacity
Never animate:
- ,
widthheight - ,
top,left,rightbottom - ,
marginpadding border-width
javascript
// GOOD - GPU accelerated
gsap.to('.card', { x: 100, y: 50, scale: 1.1, rotation: 5, opacity: 0.8 });
// BAD - Causes reflows
gsap.to('.card', { width: 200, height: 200, marginLeft: 50 });为实现60fps流畅性能,仅建议动画以下属性:
- ,
x(对应CSS的translateX, translateY)y - ,
xPercentyPercent - ,
scale,scaleXscaleY - ,
rotation,rotationXrotationY opacity
绝对避免动画以下属性:
- ,
widthheight - ,
top,left,rightbottom - ,
marginpadding border-width
javascript
// 推荐 - GPU加速
gsap.to('.card', { x: 100, y: 50, scale: 1.1, rotation: 5, opacity: 0.8 });
// 不推荐 - 会导致重排
gsap.to('.card', { width: 200, height: 200, marginLeft: 50 });ScrollTrigger Quick Start
ScrollTrigger快速入门
javascript
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
// Basic scroll-triggered animation
gsap.from('.section-content', {
opacity: 0,
y: 50,
duration: 1,
scrollTrigger: {
trigger: '.section',
start: 'top 80%', // When top of trigger hits 80% of viewport
end: 'bottom 20%',
toggleActions: 'play none none none',
// markers: true // Dev only
}
});
// Pinned section
ScrollTrigger.create({
trigger: '.sticky-section',
start: 'top top',
end: '+=100%',
pin: true,
pinSpacing: true
});
// Scrub animation (tied to scroll position)
gsap.to('.parallax-element', {
y: -100,
ease: 'none',
scrollTrigger: {
trigger: '.parallax-section',
start: 'top bottom',
end: 'bottom top',
scrub: true
}
});See scrolltrigger.md for comprehensive patterns.
javascript
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
// 基础滚动触发动画
gsap.from('.section-content', {
opacity: 0,
y: 50,
duration: 1,
scrollTrigger: {
trigger: '.section',
start: 'top 80%', // 当触发元素顶部到达视口80%位置时
end: 'bottom 20%',
toggleActions: 'play none none none',
// markers: true // 开发环境可用
}
});
// 固定区块示例
ScrollTrigger.create({
trigger: '.sticky-section',
start: 'top top',
end: '+=100%',
pin: true,
pinSpacing: true
});
// 滚动 scrub 动画(与滚动位置绑定)
gsap.to('.parallax-element', {
y: -100,
ease: 'none',
scrollTrigger: {
trigger: '.parallax-section',
start: 'top bottom',
end: 'bottom top',
scrub: true
}
});如需完整模式,请参考scrolltrigger.md。
SplitText Quick Start
SplitText快速入门
javascript
import { SplitText } from 'gsap/SplitText';
gsap.registerPlugin(SplitText);
// Split text into characters
const split = new SplitText('.headline', {
type: 'chars,words,lines',
linesClass: 'line'
});
// Animate characters
gsap.from(split.chars, {
opacity: 0,
y: 50,
rotationX: -90,
stagger: 0.02,
duration: 0.8,
ease: 'power4.out'
});
// IMPORTANT: Revert when done (or on cleanup)
// split.revert();See splittext.md for text animation patterns.
javascript
import { SplitText } from 'gsap/SplitText';
gsap.registerPlugin(SplitText);
// 将文本拆分为字符、单词、行
const split = new SplitText('.headline', {
type: 'chars,words,lines',
linesClass: 'line'
});
// 字符动画
gsap.from(split.chars, {
opacity: 0,
y: 50,
rotationX: -90,
stagger: 0.02,
duration: 0.8,
ease: 'power4.out'
});
// 重要:使用完成后(或清理时)还原
// split.revert();如需文本动画完整模式,请参考splittext.md。
Flip Plugin Quick Start
Flip插件快速入门
javascript
import { Flip } from 'gsap/Flip';
gsap.registerPlugin(Flip);
// Capture current state
const state = Flip.getState('.cards');
// Make DOM changes
container.appendChild(newCard);
// or
card.classList.toggle('expanded');
// or
filterCards();
// Animate the change
Flip.from(state, {
duration: 0.6,
ease: 'power2.inOut',
stagger: 0.05,
absolute: true, // Prevents layout shift during animation
onEnter: elements => gsap.from(elements, { opacity: 0, scale: 0.8 }),
onLeave: elements => gsap.to(elements, { opacity: 0, scale: 0.8 })
});See flip-plugin.md for layout animation patterns.
javascript
import { Flip } from 'gsap/Flip';
gsap.registerPlugin(Flip);
// 捕获当前状态
const state = Flip.getState('.cards');
// 执行DOM变更
container.appendChild(newCard);
// 或
card.classList.toggle('expanded');
// 或
filterCards();
// 为变更添加动画
Flip.from(state, {
duration: 0.6,
ease: 'power2.inOut',
stagger: 0.05,
absolute: true, // 防止动画期间布局偏移
onEnter: elements => gsap.from(elements, { opacity: 0, scale: 0.8 }),
onLeave: elements => gsap.to(elements, { opacity: 0, scale: 0.8 })
});如需布局动画完整模式,请参考flip-plugin.md。
Timeline Quick Start
时间轴快速入门
javascript
const tl = gsap.timeline({
defaults: { duration: 0.8, ease: 'power3.out' }
});
tl.from('.hero-title', { opacity: 0, y: 50 })
.from('.hero-description', { opacity: 0, y: 30 }, '-=0.5') // Overlap
.from('.hero-cta', { opacity: 0, y: 20 }, '-=0.3')
.from('.hero-image', { opacity: 0, scale: 0.9 }, '<'); // Same time as previous
// Control
tl.play();
tl.pause();
tl.reverse();
tl.seek(0.5); // Jump to 0.5 seconds
tl.progress(0.5); // Jump to 50%See timelines.md for orchestration patterns.
javascript
const tl = gsap.timeline({
defaults: { duration: 0.8, ease: 'power3.out' }
});
tl.from('.hero-title', { opacity: 0, y: 50 })
.from('.hero-description', { opacity: 0, y: 30 }, '-=0.5') // 与上一个动画重叠0.5秒
.from('.hero-cta', { opacity: 0, y: 20 }, '-=0.3')
.from('.hero-image', { opacity: 0, scale: 0.9 }, '<'); // 与上一个动画同时开始
// 时间轴控制
tl.play();
tl.pause();
tl.reverse();
tl.seek(0.5); // 跳转到0.5秒位置
tl.progress(0.5); // 跳转到50%进度位置如需编排模式完整内容,请参考timelines.md。
Common Patterns
常见动画模式
Reveal on Scroll
滚动 Reveal 动画
javascript
const mm = gsap.matchMedia();
mm.add('(prefers-reduced-motion: no-preference)', () => {
gsap.utils.toArray('.reveal').forEach(element => {
gsap.from(element, {
opacity: 0,
y: 40,
duration: 0.8,
ease: 'power3.out',
scrollTrigger: {
trigger: element,
start: 'top 85%',
toggleActions: 'play none none none'
}
});
});
});javascript
const mm = gsap.matchMedia();
mm.add('(prefers-reduced-motion: no-preference)', () => {
gsap.utils.toArray('.reveal').forEach(element => {
gsap.from(element, {
opacity: 0,
y: 40,
duration: 0.8,
ease: 'power3.out',
scrollTrigger: {
trigger: element,
start: 'top 85%',
toggleActions: 'play none none none'
}
});
});
});Horizontal Scroll Section
横向滚动区块
javascript
const mm = gsap.matchMedia();
mm.add('(prefers-reduced-motion: no-preference)', () => {
const panels = gsap.utils.toArray('.panel');
const wrapper = document.querySelector('.horizontal-wrapper');
gsap.to(panels, {
xPercent: -100 * (panels.length - 1),
ease: 'none',
scrollTrigger: {
trigger: wrapper,
pin: true,
scrub: 1,
snap: 1 / (panels.length - 1),
end: () => '+=' + wrapper.scrollWidth
}
});
});javascript
const mm = gsap.matchMedia();
mm.add('(prefers-reduced-motion: no-preference)', () => {
const panels = gsap.utils.toArray('.panel');
const wrapper = document.querySelector('.horizontal-wrapper');
gsap.to(panels, {
xPercent: -100 * (panels.length - 1),
ease: 'none',
scrollTrigger: {
trigger: wrapper,
pin: true,
scrub: 1,
snap: 1 / (panels.length - 1),
end: () => '+=' + wrapper.scrollWidth
}
});
});Magnetic Button
磁吸按钮
javascript
const button = document.querySelector('.magnetic-btn');
button.addEventListener('mousemove', (e) => {
const rect = button.getBoundingClientRect();
const x = e.clientX - rect.left - rect.width / 2;
const y = e.clientY - rect.top - rect.height / 2;
gsap.to(button, {
x: x * 0.3,
y: y * 0.3,
duration: 0.3,
ease: 'power2.out'
});
});
button.addEventListener('mouseleave', () => {
gsap.to(button, {
x: 0,
y: 0,
duration: 0.5,
ease: 'elastic.out(1, 0.3)'
});
});javascript
const button = document.querySelector('.magnetic-btn');
button.addEventListener('mousemove', (e) => {
const rect = button.getBoundingClientRect();
const x = e.clientX - rect.left - rect.width / 2;
const y = e.clientY - rect.top - rect.height / 2;
gsap.to(button, {
x: x * 0.3,
y: y * 0.3,
duration: 0.3,
ease: 'power2.out'
});
});
button.addEventListener('mouseleave', () => {
gsap.to(button, {
x: 0,
y: 0,
duration: 0.5,
ease: 'elastic.out(1, 0.3)'
});
});Text Reveal with Mask
遮罩文本 Reveal 动画
javascript
const split = new SplitText('.headline', { type: 'lines', linesClass: 'line' });
// Wrap each line in a mask container
split.lines.forEach(line => {
const wrapper = document.createElement('div');
wrapper.style.overflow = 'hidden';
line.parentNode.insertBefore(wrapper, line);
wrapper.appendChild(line);
});
gsap.from(split.lines, {
yPercent: 100,
opacity: 0,
duration: 1,
stagger: 0.1,
ease: 'power4.out'
});javascript
const split = new SplitText('.headline', { type: 'lines', linesClass: 'line' });
// 为每行文本包裹遮罩容器
split.lines.forEach(line => {
const wrapper = document.createElement('div');
wrapper.style.overflow = 'hidden';
line.parentNode.insertBefore(wrapper, line);
wrapper.appendChild(line);
});
gsap.from(split.lines, {
yPercent: 100,
opacity: 0,
duration: 1,
stagger: 0.1,
ease: 'power4.out'
});Debugging
调试技巧
javascript
// Enable dev warnings
gsap.config({
nullTargetWarn: true
});
// ScrollTrigger markers (dev only)
ScrollTrigger.defaults({
markers: process.env.NODE_ENV === 'development'
});
// Log animation state
gsap.to('.el', {
x: 100,
onUpdate: function() {
console.log('Progress:', this.progress());
}
});javascript
// 启用开发警告
gsap.config({
nullTargetWarn: true
});
// ScrollTrigger标记(仅开发环境使用)
ScrollTrigger.defaults({
markers: process.env.NODE_ENV === 'development'
});
// 记录动画状态
gsap.to('.el', {
x: 100,
onUpdate: function() {
console.log('进度:', this.progress());
}
});Framework Integration
框架集成
See framework-integration.md for:
- React with
@gsap/react - Vue composition API patterns
- Svelte lifecycle patterns
- Vanilla JS module patterns
请参考framework-integration.md获取以下内容:
- React结合的使用
@gsap/react - Vue组合式API模式
- Svelte生命周期集成模式
- 原生JS模块化模式