elite-gsap

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Elite 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

快速参考

TopicReference File
ScrollTriggerscrolltrigger.md
SplitTextsplittext.md
Flip pluginflip-plugin.md
MorphSVG & DrawSVGmorphsvg-drawsvg.md
Timelinestimelines.md
Framework integrationframework-integration.md

主题参考文档
ScrollTriggerscrolltrigger.md
SplitTextsplittext.md
Flip插件flip-plugin.md
MorphSVG & DrawSVGmorphsvg-drawsvg.md
时间轴timelines.md
框架集成framework-integration.md

Core Setup

核心配置

Installation

安装

bash
npm install gsap
bash
npm install gsap

Plugin 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
gsap.context()
to scope animations. This prevents memory leaks in SPAs and component-based frameworks.
**务必使用
gsap.context()
**来限定动画作用域。这可以防止单页应用(SPA)和组件化框架中出现内存泄漏问题。

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 ScrollTriggers
javascript
// 创建限定在容器内的上下文
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();  // 还原所有动画并销毁ScrollTrigger

Why 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
    revert()
    call cleans everything
  • 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' });  // Bezier
javascript
// 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
    ,
    y
    (translateX, translateY)
  • xPercent
    ,
    yPercent
  • scale
    ,
    scaleX
    ,
    scaleY
  • rotation
    ,
    rotationX
    ,
    rotationY
  • opacity
Never animate:
  • width
    ,
    height
  • top
    ,
    left
    ,
    right
    ,
    bottom
  • margin
    ,
    padding
  • 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
    ,
    y
    (对应CSS的translateX, translateY)
  • xPercent
    ,
    yPercent
  • scale
    ,
    scaleX
    ,
    scaleY
  • rotation
    ,
    rotationX
    ,
    rotationY
  • opacity
绝对避免动画以下属性
  • width
    ,
    height
  • top
    ,
    left
    ,
    right
    ,
    bottom
  • margin
    ,
    padding
  • 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模块化模式

Resources

资源链接