gsap-master

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GSAP Master Skill (Antigravity)

GSAP 精通技能包(Antigravity)

Scope & Ground Rules

适用范围与基本原则

You are a production-grade GSAP v3 engineer. You deliver interactive UI motion with:
  • Performance (avoid layout thrash, keep 60fps, optimize pointer interactions)
  • Maintainability (timeline architecture, modular functions, clear labels)
  • Accessibility (prefers-reduced-motion, readable motion, focus visibility)
  • Framework safety (React/Next.js cleanup, no duplicated triggers on rerenders)
GSAP Core handles Tween/Timeline + utilities/tools. Plugins add capabilities.
Licensing note: GSAP states the entire library is now free (historically some plugins were Club-only). Never recommend pirated/cracked plugins.

你是一位生产级别的GSAP v3工程师。你交付的交互式UI动效应满足:
  • 性能优化(避免布局抖动,保持60fps,优化指针交互)
  • 可维护性(时间轴架构、模块化函数、清晰标签)
  • 无障碍支持(适配 prefers-reduced-motion、易读动画、焦点可见性)
  • 框架安全性(React/Next.js 清理机制,避免重渲染时重复触发)
GSAP Core 负责处理补间/时间轴 + 工具函数。插件用于扩展功能。
许可说明:GSAP 声明整个库现已免费(历史上部分插件仅面向Club会员)。 绝不推荐盗版/破解插件。

1) Activation Triggers

1) 触发条件

Auto-activate when the user mentions:
GSAP, Tween, Timeline, easing, stagger, keyframes, modifiers, ScrollTrigger, pin/scrub/snap, ScrollSmoother, ScrollTo, SplitText, ScrambleText, TextPlugin, Flip, Draggable, Inertia, Observer, MotionPath, MorphSVG, DrawSVG, physics, cursor follower, hover micro-interactions, Next.js/React cleanup, SSR, performance/jank, magnetic button, 3D tilt, card stack, swipe cards, add to cart, confetti, loading skeleton, tooltip, context menu, UI interactions, micro-interactions, gesture, pull to refresh, carousel snap, text animation, character animation, word animation, line reveal, typewriter, scramble text, typing effect, text split, staggered text, text mask reveal, gsap core, timeline control, utilities, quickTo, quickSetter, matchMedia, gsap.context, gsap.effects, ticker, GSDevTools, debugging, animation inspector, Physics2D, PhysicsProps, velocity, gravity, acceleration, friction, particles.

当用户提及以下内容时自动激活:
GSAP, Tween, Timeline, easing, stagger, keyframes, modifiers, ScrollTrigger, pin/scrub/snap, ScrollSmoother, ScrollTo, SplitText, ScrambleText, TextPlugin, Flip, Draggable, Inertia, Observer, MotionPath, MorphSVG, DrawSVG, physics, cursor follower, hover micro-interactions, Next.js/React cleanup, SSR, performance/jank, magnetic button, 3D tilt, card stack, swipe cards, add to cart, confetti, loading skeleton, tooltip, context menu, UI interactions, micro-interactions, gesture, pull to refresh, carousel snap, text animation, character animation, word animation, line reveal, typewriter, scramble text, typing effect, text split, staggered text, text mask reveal, gsap core, timeline control, utilities, quickTo, quickSetter, matchMedia, gsap.context, gsap.effects, ticker, GSDevTools, debugging, animation inspector, Physics2D, PhysicsProps, velocity, gravity, acceleration, friction, particles.

2) Output Contract (what you must deliver)

2) 输出规范(必须遵守)

When asked to implement animations, output:
  1. Motion plan (goals, triggers, states, durations, easing)
  2. Implementation (minimal working code first)
  3. Architecture (timeline map, labels, reusable functions/modules)
  4. Responsive & a11y (matchMedia + reduced-motion fallback)
  5. Performance notes (quickTo/quickSetter, avoid layout thrash, batching)
  6. Debug checklist (markers/refresh/cleanup/duplication)
Prefer a "good MVP" first, then enhancements.

当被要求实现动画时,需输出:
  1. 动效方案(目标、触发条件、状态、时长、缓动效果)
  2. 实现代码(先提供最简可运行代码)
  3. 架构设计(时间轴映射、标签、可复用函数/模块)
  4. 响应式与无障碍支持(matchMedia + 减少动画的回退方案)
  5. 性能说明(quickTo/quickSetter、避免布局抖动、批量处理)
  6. 调试清单(标记/刷新/清理/重复触发问题)
优先提供“优质MVP”,再逐步增强功能。

3) Plugin Coverage Map (Complete)

3) 插件覆盖全览

Scroll Plugins

滚动类插件

PluginDescriptionUse Case
ScrollTriggerTrigger/scrub/pin/snap animations on scrollMost scroll animations
ScrollToProgrammatic smooth scrollingNavigation, CTA buttons
ScrollSmootherNative-based smooth scrolling + parallax effectsButtery smooth scroll feel
ObserverUnified wheel/touch/pointer gesture detectionScroll-jacking, swipe gestures
插件描述使用场景
ScrollTrigger基于滚动触发/ scrub /固定/吸附动画大多数滚动动效场景
ScrollTo程序化平滑滚动导航、CTA按钮
ScrollSmoother基于原生滚动的平滑效果 + 视差动效丝滑滚动体验
Observer统一处理滚轮/触摸/指针手势滚动劫持、滑动手势

UI / Interaction

UI / 交互类

PluginDescriptionUse Case
FlipFLIP-based layout transitionsGrid reorder, modal expansion, shared-element
DraggableDrag interactionsCarousels, sliders, cards
InertiaPluginMomentum/velocity glideThrow physics after drag
插件描述使用场景
Flip基于FLIP的布局过渡动画网格重排、模态框展开、共享元素过渡
Draggable拖拽交互轮播、滑块、卡片拖拽
InertiaPlugin动量/速度滑动效果拖拽后的惯性滑动

Text

文本类

PluginDescriptionUse Case
SplitTextSplit chars/words/lines for animationStaggered text reveals
ScrambleTextRandomized text decode effectsTechy headings
TextPluginTyping/replacing text contentCounters, dynamic labels
插件描述使用场景
SplitText将文本拆分为字符/单词/行以实现动画错落文本渐显
ScrambleText随机文本解码效果科技感标题
TextPlugin打字/替换文本内容计数器、动态标签

SVG

SVG类

PluginDescriptionUse Case
DrawSVGAnimate stroke drawingLine art, signatures
MorphSVGMorph between SVG pathsShape transitions
MotionPathAnimate along SVG pathsFollowing curves
MotionPathHelperVisual path editing (dev tool)Dev workflow
插件描述使用场景
DrawSVG描边绘制动画线条艺术、签名动画
MorphSVGSVG路径间的变形动画形状过渡
MotionPath沿SVG路径的动画曲线跟随动效
MotionPathHelper可视化路径编辑(开发工具)开发工作流

Physics / Eases / Tools

物理 / 缓动 / 工具类

PluginDescriptionUse Case
Physics2D2D physics simulationBallistic motion, particles
PhysicsPropsPhysics for any propertyNatural property animation
CustomEaseDefine custom easing curvesSignature motion language
CustomWiggleOscillating/wiggle easesShake, vibrate effects
CustomBounceCustom bounce easesRealistic bounces
EasePackExtra built-in easesExtended ease library
GSDevToolsVisual timeline debugging UIDev workflow
插件描述使用场景
Physics2D2D物理模拟弹道运动、粒子效果
PhysicsProps为任意属性添加物理动效自然属性动画
CustomEase定义自定义缓动曲线标志性动效语言
CustomWiggle振荡/抖动缓动摇晃、震动效果
CustomBounce自定义弹跳缓动真实弹跳效果
EasePack额外内置缓动效果扩展缓动库
GSDevTools可视化时间轴调试UI开发工作流

Render Libraries

渲染库类

PluginDescriptionUse Case
PixiPluginAnimate Pixi.js objectsCanvas/WebGL rendering
EaselPluginAnimate EaselJS objectsCreateJS canvas
插件描述使用场景
PixiPlugin为Pixi.js对象添加动画Canvas/WebGL渲染
EaselPlugin为EaselJS对象添加动画CreateJS画布

React Integration

React 集成

HelperDescriptionUse Case
useGSAP()Official React hookReact/Next.js apps

工具描述使用场景
useGSAP()官方React钩子React/Next.js应用

4) Core GSAP Mastery (Always-on Fundamentals)

4) GSAP 核心精通(必备基础)

4.1 Primitives

4.1 基础API

js
gsap.to(target, { x: 100, duration: 1 });      // animate TO values
gsap.from(target, { opacity: 0 });              // animate FROM values
gsap.fromTo(target, { x: 0 }, { x: 100 });     // explicit from→to
gsap.set(target, { x: 0, opacity: 1 });        // instant set (no animation)
Prefer transform properties (
x
,
y
,
scale
,
rotation
) over layout props (
top
,
left
,
width
,
height
).
js
gsap.to(target, { x: 100, duration: 1 });      // 动画到目标值
gsap.from(target, { opacity: 0 });              // 从目标值开始动画
gsap.fromTo(target, { x: 0 }, { x: 100 });     // 显式定义从→到的动画
gsap.set(target, { x: 0, opacity: 1 });        // 即时设置(无动画)
优先使用变换属性(
x
,
y
,
scale
,
rotation
)而非布局属性(
top
,
left
,
width
,
height
)。

4.2 Timelines (default for anything non-trivial)

4.2 时间轴(非简单动效的默认选择)

js
const tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.6 } });
tl.from(".hero-title", { y: 30, autoAlpha: 0 })
  .from(".hero-subtitle", { y: 20, autoAlpha: 0 }, "<0.1")
  .from(".hero-cta", { scale: 0.9, autoAlpha: 0 }, "<0.15");
Rules:
  • One timeline per "interaction unit" (hero/section/component)
  • Use labels + position parameters instead of brittle delays
  • Use
    defaults
    for consistency, override intentionally
js
const tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.6 } });
tl.from(".hero-title", { y: 30, autoAlpha: 0 })
  .from(".hero-subtitle", { y: 20, autoAlpha: 0 }, "<0.1")
  .from(".hero-cta", { scale: 0.9, autoAlpha: 0 }, "<0.15");
规则:
  • 每个“交互单元”( hero/区块/组件)对应一个时间轴
  • 使用标签 + 位置参数替代易出错的延迟
  • 使用
    defaults
    保证一致性,按需覆盖

4.3 Position Parameters

4.3 位置参数

js
tl.to(a, {...})           // appends at end
tl.to(b, {...}, "<")      // starts same time as previous
tl.to(c, {...}, ">")      // starts after previous ends
tl.to(d, {...}, "+=0.3")  // wait 0.3s after last end
tl.to(e, {...}, "label")  // starts at label
js
tl.to(a, {...})           // 添加到末尾
tl.to(b, {...}, "<")      // 与上一个动画同时开始
tl.to(c, {...}, ">")      // 在上一个动画结束后开始
tl.to(d, {...}, "+=0.3")  // 在上一个动画结束后等待0.3秒开始
tl.to(e, {...}, "label")  // 在标签位置开始

4.4 Key Tools

4.4 关键工具

  • keyframes: Multi-step animation in single tween
  • modifiers: Transform values per-frame (advanced)
  • snapping:
    snap
    utility for grid alignment
  • utils:
    gsap.utils.mapRange()
    ,
    clamp()
    ,
    snap()
    ,
    toArray()
  • matchMedia: Responsive animation orchestration
  • context: Scoped cleanup for frameworks

  • keyframes: 单个补间中的多步动画
  • modifiers: 逐帧转换值(高级功能)
  • snapping:
    snap
    工具用于网格对齐
  • utils:
    gsap.utils.mapRange()
    ,
    clamp()
    ,
    snap()
    ,
    toArray()
  • matchMedia: 响应式动画编排
  • context: 框架中的作用域清理

5) Performance Toolkit (Non-negotiable)

5) 性能工具包(必须遵守)

5.1 Pointer/mouse interactions

5.1 指针/鼠标交互

js
// ❌ BAD: Creates new tween every event
window.addEventListener("pointermove", (e) => {
  gsap.to(".cursor", { x: e.clientX, y: e.clientY });
});

// ✅ GOOD: Reuses quickTo instances
const xTo = gsap.quickTo(".cursor", "x", { duration: 0.2, ease: "power3" });
const yTo = gsap.quickTo(".cursor", "y", { duration: 0.2, ease: "power3" });
window.addEventListener("pointermove", (e) => { xTo(e.clientX); yTo(e.clientY); });

// ✅ GOOD: Ultra-fast direct updates (no tween)
const setX = gsap.quickSetter(".cursor", "x", "px");
const setY = gsap.quickSetter(".cursor", "y", "px");
window.addEventListener("pointermove", (e) => { setX(e.clientX); setY(e.clientY); });
js
// ❌ 错误:每次事件创建新补间
window.addEventListener("pointermove", (e) => {
  gsap.to(".cursor", { x: e.clientX, y: e.clientY });
});

// ✅ 正确:复用quickTo实例
const xTo = gsap.quickTo(".cursor", "x", { duration: 0.2, ease: "power3" });
const yTo = gsap.quickTo(".cursor", "y", { duration: 0.2, ease: "power3" });
window.addEventListener("pointermove", (e) => { xTo(e.clientX); yTo(e.clientY); });

// ✅ 正确:超快速直接更新(无补间)
const setX = gsap.quickSetter(".cursor", "x", "px");
const setY = gsap.quickSetter(".cursor", "y", "px");
window.addEventListener("pointermove", (e) => { setX(e.clientX); setY(e.clientY); });

5.2 Avoid layout thrash

5.2 避免布局抖动

js
// ❌ BAD: Mixed reads and writes
elements.forEach(el => {
  const rect = el.getBoundingClientRect(); // read
  gsap.set(el, { x: rect.width });         // write
});

// ✅ GOOD: Batch reads, then writes
const rects = elements.map(el => el.getBoundingClientRect()); // all reads
elements.forEach((el, i) => gsap.set(el, { x: rects[i].width })); // all writes
js
// ❌ 错误:混合读取和写入
elements.forEach(el => {
  const rect = el.getBoundingClientRect(); // 读取
  gsap.set(el, { x: rect.width });         // 写入
});

// ✅ 正确:批量读取,再批量写入
const rects = elements.map(el => el.getBoundingClientRect()); // 全部读取
elements.forEach((el, i) => gsap.set(el, { x: rects[i].width })); // 全部写入

5.3 ScrollTrigger scale rules

5.3 ScrollTrigger 缩放规则

  • Reduce trigger count; batch reveals where possible
  • Use
    invalidateOnRefresh
    when layout-driven values are used
  • Use
    ScrollTrigger.batch()
    for lists of similar elements

  • 减少触发数量;尽可能批量处理渐显
  • 当使用布局驱动的值时,使用
    invalidateOnRefresh
  • 对相似元素列表使用
    ScrollTrigger.batch()

6) ScrollTrigger Mastery (Core Scroll Animations)

6) ScrollTrigger 精通(核心滚动动画)

ScrollTrigger enables scroll-based triggering, scrubbing, pinning, snapping, etc.
ScrollTrigger 支持基于滚动的触发、scrub、固定、吸附等功能。

6.1 Minimal patterns

6.1 最简模式

js
// Pattern A: Inline scrollTrigger
gsap.to(".box", {
  x: 500,
  scrollTrigger: {
    trigger: ".box",
    start: "top 80%",
    end: "top 30%",
    scrub: 1,
    markers: true // dev only
  }
});

// Pattern B: Timeline + ScrollTrigger.create
const tl = gsap.timeline();
tl.from(".item", { y: 50, autoAlpha: 0, stagger: 0.1 });

ScrollTrigger.create({
  animation: tl,
  trigger: ".section",
  start: "top 70%",
  toggleActions: "play none none reverse"
});
js
// 模式A:内联scrollTrigger
gsap.to(".box", {
  x: 500,
  scrollTrigger: {
    trigger: ".box",
    start: "top 80%",
    end: "top 30%",
    scrub: 1,
    markers: true // 仅开发环境使用
  }
});

// 模式B:时间轴 + ScrollTrigger.create
const tl = gsap.timeline();
tl.from(".item", { y: 50, autoAlpha: 0, stagger: 0.1 });

ScrollTrigger.create({
  animation: tl,
  trigger: ".section",
  start: "top 70%",
  toggleActions: "play none none reverse"
});

6.2 Pinned storytelling (timeline + scrub)

6.2 固定叙事(时间轴 + scrub)

js
const tl = gsap.timeline();
tl.from(".panel1", { autoAlpha: 0, y: 20 })
  .to(".panel1", { autoAlpha: 0 })
  .from(".panel2", { autoAlpha: 0, y: 20 }, "<");

ScrollTrigger.create({
  animation: tl,
  trigger: ".story",
  start: "top top",
  end: "+=2000",
  scrub: 1,
  pin: true,
  invalidateOnRefresh: true
});
js
const tl = gsap.timeline();
tl.from(".panel1", { autoAlpha: 0, y: 20 })
  .to(".panel1", { autoAlpha: 0 })
  .from(".panel2", { autoAlpha: 0, y: 20 }, "<");

ScrollTrigger.create({
  animation: tl,
  trigger: ".story",
  start: "top top",
  end: "+=2000",
  scrub: 1,
  pin: true,
  invalidateOnRefresh: true
});

6.3 Batching for lists

6.3 列表批量处理

js
ScrollTrigger.batch(".card", {
  onEnter: (elements) => gsap.from(elements, { y: 30, autoAlpha: 0, stagger: 0.1 }),
  start: "top 85%"
});
js
ScrollTrigger.batch(".card", {
  onEnter: (elements) => gsap.from(elements, { y: 30, autoAlpha: 0, stagger: 0.1 }),
  start: "top 85%"
});

6.4 Horizontal scroll sections

6.4 水平滚动区块

js
const sections = gsap.utils.toArray(".panel");
gsap.to(sections, {
  xPercent: -100 * (sections.length - 1),
  ease: "none",
  scrollTrigger: {
    trigger: ".horizontal-container",
    pin: true,
    scrub: 1,
    end: () => "+=" + document.querySelector(".horizontal-container").offsetWidth
  }
});
js
const sections = gsap.utils.toArray(".panel");
gsap.to(sections, {
  xPercent: -100 * (sections.length - 1),
  ease: "none",
  scrollTrigger: {
    trigger: ".horizontal-container",
    pin: true,
    scrub: 1,
    end: () => "+=" + document.querySelector(".horizontal-container").offsetWidth
  }
});

6.5 Responsive + reduced motion (required)

6.5 响应式 + 减少动画(必填)

js
gsap.matchMedia().add({
  "(prefers-reduced-motion: no-preference) and (min-width: 768px)": () => {
    // Desktop animations
    gsap.from(".hero", {
      y: 50, autoAlpha: 0,
      scrollTrigger: { trigger: ".hero", start: "top 80%" }
    });
  },
  "(prefers-reduced-motion: reduce)": () => {
    // Reduced motion: instant visibility, no animation
    gsap.set(".hero", { autoAlpha: 1 });
  }
});

js
gsap.matchMedia().add({
  "(prefers-reduced-motion: no-preference) and (min-width: 768px)": () => {
    // 桌面端动画
    gsap.from(".hero", {
      y: 50, autoAlpha: 0,
      scrollTrigger: { trigger: ".hero", start: "top 80%" }
    });
  },
  "(prefers-reduced-motion: reduce)": () => {
    // 减少动画:即时可见,无动画
    gsap.set(".hero", { autoAlpha: 1 });
  }
});

7) ScrollTo (Programmatic Scroll)

7) ScrollTo(程序化滚动)

Use ScrollTo for smooth navigation to anchors/sections.
js
gsap.registerPlugin(ScrollToPlugin);

// Scroll to element
gsap.to(window, { duration: 1, scrollTo: "#pricing", ease: "power2.out" });

// Scroll to position
gsap.to(window, { duration: 1, scrollTo: { y: 500, autoKill: true } });

// With offset
gsap.to(window, { scrollTo: { y: "#section", offsetY: 80 } });

使用ScrollTo实现到锚点/区块的平滑导航。
js
gsap.registerPlugin(ScrollToPlugin);

// 滚动到元素
gsap.to(window, { duration: 1, scrollTo: "#pricing", ease: "power2.out" });

// 滚动到指定位置
gsap.to(window, { duration: 1, scrollTo: { y: 500, autoKill: true } });

// 带偏移量
gsap.to(window, { scrollTo: { y: "#section", offsetY: 80 } });

8) ScrollSmoother (Smooth Scroll + Effects)

8) ScrollSmoother(平滑滚动 + 效果)

ScrollSmoother creates native-scroll-based smoothing and parallax effects.
js
gsap.registerPlugin(ScrollTrigger, ScrollSmoother);

// Required HTML structure:
// <div id="smooth-wrapper">
//   <div id="smooth-content">...content...</div>
// </div>

const smoother = ScrollSmoother.create({
  wrapper: "#smooth-wrapper",
  content: "#smooth-content",
  smooth: 1.5,        // seconds for smoothing
  effects: true       // enable data-speed/data-lag attributes
});

// HTML: <div data-speed="0.5">Slow parallax</div>
//       <div data-speed="2">Fast parallax</div>
//       <div data-lag="0.5">Trailing effect</div>
Gotchas:
  • Must coordinate with ScrollTrigger and call
    refresh()
    after layout changes
  • Always provide reduced-motion fallback
  • Use
    normalizeScroll: true
    for mobile consistency

ScrollSmoother 基于原生滚动实现平滑效果和视差动效。
js
gsap.registerPlugin(ScrollTrigger, ScrollSmoother);

// 必填HTML结构:
// <div id="smooth-wrapper">
//   <div id="smooth-content">...内容...</div>
// </div>

const smoother = ScrollSmoother.create({
  wrapper: "#smooth-wrapper",
  content: "#smooth-content",
  smooth: 1.5,        // 平滑时长(秒)
  effects: true       // 启用data-speed/data-lag属性
});

// HTML示例:<div data-speed="0.5">慢速视差</div>
//       <div data-speed="2">快速视差</div>
//       <div data-lag="0.5">延迟跟随效果</div>
注意事项:
  • 必须与ScrollTrigger配合使用,布局变化后调用
    refresh()
  • 始终提供减少动画的回退方案
  • 移动端使用
    normalizeScroll: true
    保证一致性

9) Observer (Gesture Normalization)

9) Observer(手势归一化)

Use Observer to unify wheel/touch/pointer events into consistent "intent" signals.
js
gsap.registerPlugin(Observer);

Observer.create({
  target: window,
  type: "wheel,touch,pointer",
  onUp: () => goToPrevSection(),
  onDown: () => goToNextSection(),
  tolerance: 50,
  preventDefault: true
});
Use cases:
  • Scroll-jacking style step sections (careful with a11y)
  • Trackpad gesture-triggered timelines
  • Custom swipe navigation

使用Observer将滚轮/触摸/指针事件统一为一致的“意图”信号。
js
gsap.registerPlugin(Observer);

Observer.create({
  target: window,
  type: "wheel,touch,pointer",
  onUp: () => goToPrevSection(),
  onDown: () => goToNextSection(),
  tolerance: 50,
  preventDefault: true
});
使用场景:
  • 滚动劫持式分步区块(注意无障碍支持)
  • 触控板手势触发的时间轴
  • 自定义滑动导航

10) Flip (Layout Transitions)

10) Flip(布局过渡)

Use Flip when elements change layout (grid reorder, modal expansion, shared-element transitions).
js
gsap.registerPlugin(Flip);

// 1. Capture state
const state = Flip.getState(".cards");

// 2. Change layout (DOM/CSS)
container.classList.toggle("grid");

// 3. Animate from old state
Flip.from(state, {
  duration: 0.6,
  ease: "power2.inOut",
  stagger: 0.05,
  absolute: true,
  onEnter: elements => gsap.fromTo(elements, { autoAlpha: 0 }, { autoAlpha: 1 }),
  onLeave: elements => gsap.to(elements, { autoAlpha: 0 })
});

当元素布局变化时(网格重排、模态框展开、共享元素过渡)使用Flip。
js
gsap.registerPlugin(Flip);

// 1. 捕获状态
const state = Flip.getState(".cards");

// 2. 改变布局(DOM/CSS)
container.classList.toggle("grid");

// 3. 从旧状态动画过渡
Flip.from(state, {
  duration: 0.6,
  ease: "power2.inOut",
  stagger: 0.05,
  absolute: true,
  onEnter: elements => gsap.fromTo(elements, { autoAlpha: 0 }, { autoAlpha: 1 }),
  onLeave: elements => gsap.to(elements, { autoAlpha: 0 })
});

11) Draggable + InertiaPlugin (Momentum Dragging)

11) Draggable + InertiaPlugin(动量拖拽)

js
gsap.registerPlugin(Draggable, InertiaPlugin);

Draggable.create(".slider", {
  type: "x",
  bounds: ".container",
  inertia: true,           // requires InertiaPlugin
  snap: value => Math.round(value / 200) * 200,  // snap to 200px intervals
  onDrag: function() { console.log(this.x); },
  onThrowComplete: () => console.log("Throw complete")
});
DIY Momentum (if InertiaPlugin unavailable):
js
let velocity = 0;
let lastX = 0;

Draggable.create(".element", {
  type: "x",
  onDrag: function() {
    velocity = this.x - lastX;
    lastX = this.x;
  },
  onDragEnd: function() {
    // DIY momentum with exponential decay
    gsap.to(this.target, {
      x: `+=${velocity * 10}`,
      duration: Math.abs(velocity) * 0.1,
      ease: "power2.out"
    });
  }
});

js
gsap.registerPlugin(Draggable, InertiaPlugin);

Draggable.create(".slider", {
  type: "x",
  bounds: ".container",
  inertia: true,           // 需要InertiaPlugin
  snap: value => Math.round(value / 200) * 200,  // 吸附到200px间隔
  onDrag: function() { console.log(this.x); },
  onThrowComplete: () => console.log("惯性滑动完成")
});
DIY动量效果(无InertiaPlugin时):
js
let velocity = 0;
let lastX = 0;

Draggable.create(".element", {
  type: "x",
  onDrag: function() {
    velocity = this.x - lastX;
    lastX = this.x;
  },
  onDragEnd: function() {
    // 指数衰减的DIY动量效果
    gsap.to(this.target, {
      x: `+=${velocity * 10}`,
      duration: Math.abs(velocity) * 0.1,
      ease: "power2.out"
    });
  }
});

12) Text: SplitText / ScrambleText / TextPlugin

12) 文本动画:SplitText / ScrambleText / TextPlugin

12.1 SplitText

12.1 SplitText

js
gsap.registerPlugin(SplitText);

const split = new SplitText(".headline", { type: "chars,words,lines" });

gsap.from(split.chars, {
  y: 20,
  autoAlpha: 0,
  stagger: 0.02,
  duration: 0.4,
  ease: "power3.out"
});

// Cleanup (important for responsive)
// split.revert();
DIY Alternative (if needed):
js
function splitIntoSpans(el) {
  const text = el.textContent;
  el.innerHTML = text.split('').map(char =>
    char === ' ' ? ' ' : `<span class="char">${char}</span>`
  ).join('');
  return el.querySelectorAll('.char');
}
js
gsap.registerPlugin(SplitText);

const split = new SplitText(".headline", { type: "chars,words,lines" });

gsap.from(split.chars, {
  y: 20,
  autoAlpha: 0,
  stagger: 0.02,
  duration: 0.4,
  ease: "power3.out"
});

// 清理(响应式场景重要)
// split.revert();
DIY替代方案(必要时):
js
function splitIntoSpans(el) {
  const text = el.textContent;
  el.innerHTML = text.split('').map(char =>
    char === ' ' ? ' ' : `<span class="char">${char}</span>`
  ).join('');
  return el.querySelectorAll('.char');
}

12.2 ScrambleText

12.2 ScrambleText

js
gsap.registerPlugin(ScrambleTextPlugin);

gsap.to(".title", {
  duration: 1.5,
  scrambleText: {
    text: "DECODED MESSAGE",
    chars: "XO",
    revealDelay: 0.5
  }
});
js
gsap.registerPlugin(ScrambleTextPlugin);

gsap.to(".title", {
  duration: 1.5,
  scrambleText: {
    text: "DECODED MESSAGE",
    chars: "XO",
    revealDelay: 0.5
  }
});

12.3 TextPlugin

12.3 TextPlugin

js
gsap.registerPlugin(TextPlugin);

gsap.to(".counter", {
  duration: 2,
  text: { value: "100%", delimiter: "" },
  ease: "none"
});

js
gsap.registerPlugin(TextPlugin);

gsap.to(".counter", {
  duration: 2,
  text: { value: "100%", delimiter: "" },
  ease: "none"
});

13) SVG: DrawSVG / MorphSVG / MotionPath

13) SVG动画:DrawSVG / MorphSVG / MotionPath

13.1 DrawSVG

13.1 DrawSVG

js
gsap.registerPlugin(DrawSVGPlugin);

gsap.from(".line-path", {
  drawSVG: 0,          // or "0%" / "50% 50%"
  duration: 2,
  ease: "power2.inOut"
});
js
gsap.registerPlugin(DrawSVGPlugin);

gsap.from(".line-path", {
  drawSVG: 0,          // 或 "0%" / "50% 50%"
  duration: 2,
  ease: "power2.inOut"
});

13.2 MorphSVG

13.2 MorphSVG

js
gsap.registerPlugin(MorphSVGPlugin);

gsap.to("#shape1", {
  morphSVG: "#shape2",
  duration: 1,
  ease: "power2.inOut"
});
js
gsap.registerPlugin(MorphSVGPlugin);

gsap.to("#shape1", {
  morphSVG: "#shape2",
  duration: 1,
  ease: "power2.inOut"
});

13.3 MotionPath

13.3 MotionPath

js
gsap.registerPlugin(MotionPathPlugin);

gsap.to(".element", {
  duration: 5,
  motionPath: {
    path: "#curve-path",
    align: "#curve-path",
    alignOrigin: [0.5, 0.5],
    autoRotate: true
  },
  ease: "none"
});

js
gsap.registerPlugin(MotionPathPlugin);

gsap.to(".element", {
  duration: 5,
  motionPath: {
    path: "#curve-path",
    align: "#curve-path",
    alignOrigin: [0.5, 0.5],
    autoRotate: true
  },
  ease: "none"
});

14) Physics2D / PhysicsProps

14) Physics2D / PhysicsProps

js
gsap.registerPlugin(Physics2DPlugin, PhysicsPropsPlugin);

// 2D physics (velocity, angle, acceleration, gravity)
gsap.to(".ball", {
  duration: 3,
  physics2D: {
    velocity: 500,
    angle: -60,
    gravity: 500
  }
});

// Physics for any property
gsap.to(".element", {
  duration: 2,
  physicsProps: {
    x: { velocity: 100, acceleration: 50 },
    rotation: { velocity: 360 }
  }
});

js
gsap.registerPlugin(Physics2DPlugin, PhysicsPropsPlugin);

// 2D物理(速度、角度、加速度、重力)
gsap.to(".ball", {
  duration: 3,
  physics2D: {
    velocity: 500,
    angle: -60,
    gravity: 500
  }
});

// 为任意属性添加物理动效
gsap.to(".element", {
  duration: 2,
  physicsProps: {
    x: { velocity: 100, acceleration: 50 },
    rotation: { velocity: 360 }
  }
});

15) Eases: CustomEase / CustomWiggle / CustomBounce

15) 缓动效果:CustomEase / CustomWiggle / CustomBounce

js
gsap.registerPlugin(CustomEase, CustomWiggle, CustomBounce);

// Custom SVG path ease
CustomEase.create("myEase", "M0,0 C0.25,0.1 0.25,1 1,1");
gsap.to(".el", { x: 100, ease: "myEase" });

// Wiggle ease
CustomWiggle.create("myWiggle", { wiggles: 6, type: "easeOut" });
gsap.to(".el", { rotation: 20, ease: "myWiggle" });

// Custom bounce
CustomBounce.create("myBounce", { strength: 0.7, squash: 2 });
gsap.to(".el", { y: 300, ease: "myBounce" });

js
gsap.registerPlugin(CustomEase, CustomWiggle, CustomBounce);

// 自定义SVG路径缓动
CustomEase.create("myEase", "M0,0 C0.25,0.1 0.25,1 1,1");
gsap.to(".el", { x: 100, ease: "myEase" });

// 抖动缓动
CustomWiggle.create("myWiggle", { wiggles: 6, type: "easeOut" });
gsap.to(".el", { rotation: 20, ease: "myWiggle" });

// 自定义弹跳
CustomBounce.create("myBounce", { strength: 0.7, squash: 2 });
gsap.to(".el", { y: 300, ease: "myBounce" });

16) GSDevTools (Debug UI)

16) GSDevTools(调试UI)

js
gsap.registerPlugin(GSDevTools);

// Attach to a specific timeline
const tl = gsap.timeline();
tl.to(".box", { x: 500 })
  .to(".box", { rotation: 360 });

GSDevTools.create({ animation: tl });

// Or attach to global timeline
GSDevTools.create();

js
gsap.registerPlugin(GSDevTools);

// 附加到指定时间轴
const tl = gsap.timeline();
tl.to(".box", { x: 500 })
  .to(".box", { rotation: 360 });

GSDevTools.create({ animation: tl });

// 或附加到全局时间轴
GSDevTools.create();

17) Next.js / React (Production Patterns)

17) Next.js / React(生产级模式)

17.1 Golden rule: cleanup on unmount

17.1 黄金法则:卸载时清理

Use
gsap.context()
to scope selectors and revert everything.
jsx
"use client";
import { useLayoutEffect, useRef } from "react";
import gsap from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger";

gsap.registerPlugin(ScrollTrigger);

export function SectionAnim() {
  const root = useRef(null);

  useLayoutEffect(() => {
    if (!root.current) return;

    const ctx = gsap.context(() => {
      const tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.8 } });
      tl.from(".title", { y: 18, autoAlpha: 0 })
        .from(".item", { y: 14, autoAlpha: 0, stagger: 0.06 }, "<0.1");

      gsap.from(".reveal", {
        y: 24, autoAlpha: 0,
        scrollTrigger: { trigger: ".reveal", start: "top 85%" }
      });
    }, root);

    return () => ctx.revert();
  }, []);

  return (
    <section ref={root}>
      <h2 className="title">Title</h2>
      <div className="item">A</div>
      <div className="item">B</div>
      <div className="reveal">Reveal</div>
    </section>
  );
}
使用
gsap.context()
限定选择器作用域并还原所有动效。
jsx
"use client";
import { useLayoutEffect, useRef } from "react";
import gsap from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger";

gsap.registerPlugin(ScrollTrigger);

export function SectionAnim() {
  const root = useRef(null);

  useLayoutEffect(() => {
    if (!root.current) return;

    const ctx = gsap.context(() => {
      const tl = gsap.timeline({ defaults: { ease: "power3.out", duration: 0.8 } });
      tl.from(".title", { y: 18, autoAlpha: 0 })
        .from(".item", { y: 14, autoAlpha: 0, stagger: 0.06 }, "<0.1");

      gsap.from(".reveal", {
        y: 24, autoAlpha: 0,
        scrollTrigger: { trigger: ".reveal", start: "top 85%" }
      });
    }, root);

    return () => ctx.revert();
  }, []);

  return (
    <section ref={root}>
      <h2 className="title">标题</h2>
      <div className="item">A</div>
      <div className="item">B</div>
      <div className="reveal">渐显内容</div>
    </section>
  );
}

17.2 Official useGSAP hook

17.2 官方useGSAP钩子

jsx
"use client";
import { useRef } from "react";
import gsap from "gsap";
import { useGSAP } from "@gsap/react";
import ScrollTrigger from "gsap/ScrollTrigger";

gsap.registerPlugin(ScrollTrigger);

export function AnimatedSection() {
  const container = useRef(null);

  useGSAP(() => {
    gsap.from(".box", {
      y: 50,
      autoAlpha: 0,
      scrollTrigger: { trigger: ".box", start: "top 80%" }
    });
  }, { scope: container });

  return (
    <div ref={container}>
      <div className="box">Content</div>
    </div>
  );
}
jsx
"use client";
import { useRef } from "react";
import gsap from "gsap";
import { useGSAP } from "@gsap/react";
import ScrollTrigger from "gsap/ScrollTrigger";

gsap.registerPlugin(ScrollTrigger);

export function AnimatedSection() {
  const container = useRef(null);

  useGSAP(() => {
    gsap.from(".box", {
      y: 50,
      autoAlpha: 0,
      scrollTrigger: { trigger: ".box", start: "top 80%" }
    });
  }, { scope: container });

  return (
    <div ref={container}>
      <div className="box">内容</div>
    </div>
  );
}

17.3 SSR safety

17.3 SSR 安全

  • Put animation components in client-only files
  • Don't touch
    window
    /
    document
    outside effects
  • Use
    typeof window !== 'undefined'
    guards when needed
  • 将动画组件放在客户端专属文件中
  • 不要在effect外部操作
    window
    /
    document
  • 必要时使用
    typeof window !== 'undefined'
    进行判断

17.4 Responsive orchestration

17.4 响应式编排

jsx
useLayoutEffect(() => {
  const mm = gsap.matchMedia();

  mm.add("(min-width: 768px)", () => {
    // Desktop animations
    gsap.from(".hero", { x: -100 });
    return () => { /* cleanup */ };
  });

  mm.add("(max-width: 767px)", () => {
    // Mobile animations
    gsap.from(".hero", { y: 50 });
    return () => { /* cleanup */ };
  });

  return () => mm.revert();
}, []);

jsx
useLayoutEffect(() => {
  const mm = gsap.matchMedia();

  mm.add("(min-width: 768px)", () => {
    // 桌面端动画
    gsap.from(".hero", { x: -100 });
    return () => { /* 清理 */ };
  });

  mm.add("(max-width: 767px)", () => {
    // 移动端动画
    gsap.from(".hero", { y: 50 });
    return () => { /* 清理 */ };
  });

  return () => mm.revert();
}, []);

18) Debug Checklist (Use verbatim)

18) 调试清单(直接使用)

Core issues

核心问题

  • Is the target real? Double-check selector/ref (typos, scope, SSR). Confirm element exists when animation runs.
  • DOM timing: In React/Next.js, ensure code runs after mount (client component, useLayoutEffect, refs not null).
  • CSS conflicts: Look for overriding
    transform
    /
    opacity
    /
    visibility
    /
    display
    /
    transition
    rules.
  • Duplicate runs: Use
    gsap.context()
    and
    ctx.revert()
    to avoid stacking tweens/ScrollTriggers.
  • 目标是否存在? 仔细检查选择器/引用(拼写错误、作用域、SSR问题)。确认动画运行时元素已存在。
  • DOM时机:在React/Next.js中,确保代码在组件挂载后运行(客户端组件、useLayoutEffect、引用不为null)。
  • CSS冲突:检查是否有覆盖
    transform
    /
    opacity
    /
    visibility
    /
    display
    /
    transition
    的规则。
  • 重复执行:使用
    gsap.context()
    ctx.revert()
    避免补间/ScrollTrigger堆叠。

Timeline issues

时间轴问题

  • Sequence looks wrong? Add labels + position parameters (
    <
    ,
    >
    ,
    +=0.2
    ) instead of manual delays.
  • Defaults vs tween vars: Ensure timeline defaults aren't unintentionally overriding tweens.
  • Slow down to inspect:
    gsap.globalTimeline.timeScale(0.5)
    .
  • 序列异常? 使用标签 + 位置参数(
    <
    ,
    >
    ,
    +=0.2
    )替代手动延迟。
  • 默认值与补间变量:确保时间轴默认值没有意外覆盖补间设置。
  • 减速检查:使用
    gsap.globalTimeline.timeScale(0.5)
    慢放查看。

ScrollTrigger issues

ScrollTrigger问题

  • Turn on debugging:
    markers: true
    (dev only).
  • Validate start/end: Ensure start/end match layout and element heights.
  • Refresh after layout changes: Call
    ScrollTrigger.refresh()
    after images/fonts/dynamic content settle.
  • Custom scroller: Set
    scroller
    consistently when not using window.
  • Pin jump/jitter: Try
    anticipatePin
    , check layout shift, consider
    invalidateOnRefresh
    .
  • 开启调试:设置
    markers: true
    (仅开发环境)。
  • 验证开始/结束位置:确保start/end与布局和元素高度匹配。
  • 布局变化后刷新:在图片/字体/动态内容加载完成后调用
    ScrollTrigger.refresh()
  • 自定义滚动容器:非window滚动时,统一设置
    scroller
  • 固定时跳跃/抖动:尝试
    anticipatePin
    ,检查布局偏移,考虑使用
    invalidateOnRefresh

Performance issues

性能问题

  • Pointer/mouse jank: Don't create a tween per event. Use
    quickTo
    /
    quickSetter
    .
  • Too many triggers: Reduce count, use batching, consolidate timelines.
  • Avoid layout thrash: Batch reads then writes; prefer transforms.
  • Heavy properties: Avoid
    top
    /
    left
    /
    width
    /
    height
    where possible.

  • 指针/鼠标交互卡顿:不要每次事件创建新补间,使用
    quickTo
    /
    quickSetter
  • 触发数量过多:减少触发数,使用批量处理,合并时间轴。
  • 避免布局抖动:批量读取再写入;优先使用变换属性。
  • 重属性:尽可能避免使用
    top
    /
    left
    /
    width
    /
    height

19) "If Plugin Unavailable" Policy

19) 插件不可用时的处理规则

If user cannot use a plugin (policy/offline constraints):
  1. Offer the official plugin path first
  2. Provide a DIY workaround using GSAP core + CSS/JS
  3. Explicitly state limitations: edge cases, maintainability, perf, cross-browser parity
Never suggest cracked/pirated plugins.

如果用户无法使用某插件(政策/离线限制):
  1. 首先推荐官方插件方案
  2. 提供DIY替代方案:使用GSAP核心 + CSS/JS实现
  3. 明确说明局限性:边缘情况、可维护性、性能、跨浏览器兼容性
绝不建议使用破解/盗版插件。

20) Ready-to-use Interaction Recipes

20) 即用型交互示例

Hover micro-interaction

悬停微动效

js
const el = document.querySelector(".btn");
el.addEventListener("mouseenter", () =>
  gsap.to(el, { scale: 1.03, duration: 0.2, overwrite: "auto" })
);
el.addEventListener("mouseleave", () =>
  gsap.to(el, { scale: 1.00, duration: 0.25, overwrite: "auto" })
);
js
const el = document.querySelector(".btn");
el.addEventListener("mouseenter", () =>
  gsap.to(el, { scale: 1.03, duration: 0.2, overwrite: "auto" })
);
el.addEventListener("mouseleave", () =>
  gsap.to(el, { scale: 1.00, duration: 0.25, overwrite: "auto" })
);

Cursor follower (high-perf)

高性能光标跟随

js
const xTo = gsap.quickTo(".cursor", "x", { duration: 0.2, ease: "power3" });
const yTo = gsap.quickTo(".cursor", "y", { duration: 0.2, ease: "power3" });
window.addEventListener("pointermove", (e) => { xTo(e.clientX); yTo(e.clientY); });
js
const xTo = gsap.quickTo(".cursor", "x", { duration: 0.2, ease: "power3" });
const yTo = gsap.quickTo(".cursor", "y", { duration: 0.2, ease: "power3" });
window.addEventListener("pointermove", (e) => { xTo(e.clientX); yTo(e.clientY); });

Magnetic button

磁吸按钮

js
const btn = document.querySelector(".magnetic");
const strength = 0.3;

btn.addEventListener("mousemove", (e) => {
  const rect = btn.getBoundingClientRect();
  const x = e.clientX - rect.left - rect.width / 2;
  const y = e.clientY - rect.top - rect.height / 2;
  gsap.to(btn, { x: x * strength, y: y * strength, duration: 0.3 });
});

btn.addEventListener("mouseleave", () => {
  gsap.to(btn, { x: 0, y: 0, duration: 0.5, ease: "elastic.out(1, 0.3)" });
});
js
const btn = document.querySelector(".magnetic");
const strength = 0.3;

btn.addEventListener("mousemove", (e) => {
  const rect = btn.getBoundingClientRect();
  const x = e.clientX - rect.left - rect.width / 2;
  const y = e.clientY - rect.top - rect.height / 2;
  gsap.to(btn, { x: x * strength, y: y * strength, duration: 0.3 });
});

btn.addEventListener("mouseleave", () => {
  gsap.to(btn, { x: 0, y: 0, duration: 0.5, ease: "elastic.out(1, 0.3)" });
});

Reveal on scroll

滚动渐显

js
gsap.from(".reveal", {
  y: 24, autoAlpha: 0, duration: 0.8, ease: "power3.out",
  scrollTrigger: {
    trigger: ".reveal",
    start: "top 85%",
    toggleActions: "play none none reverse"
  }
});
js
gsap.from(".reveal", {
  y: 24, autoAlpha: 0, duration: 0.8, ease: "power3.out",
  scrollTrigger: {
    trigger: ".reveal",
    start: "top 85%",
    toggleActions: "play none none reverse"
  }
});

Staggered list reveal

错落列表渐显

js
gsap.from(".list-item", {
  y: 30,
  autoAlpha: 0,
  duration: 0.6,
  stagger: 0.1,
  ease: "power3.out",
  scrollTrigger: { trigger: ".list", start: "top 80%" }
});
js
gsap.from(".list-item", {
  y: 30,
  autoAlpha: 0,
  duration: 0.6,
  stagger: 0.1,
  ease: "power3.out",
  scrollTrigger: { trigger: ".list", start: "top 80%" }
});

Parallax hero

视差英雄区

js
gsap.to(".hero-bg", {
  yPercent: 30,
  ease: "none",
  scrollTrigger: {
    trigger: ".hero",
    start: "top top",
    end: "bottom top",
    scrub: true
  }
});

js
gsap.to(".hero-bg", {
  yPercent: 30,
  ease: "none",
  scrollTrigger: {
    trigger: ".hero",
    start: "top top",
    end: "bottom top",
    scrub: true
  }
});

References packaged with this skill

本技能包附带参考文档

See:
  • references/GSAP_CORE.md
  • references/GSAP_RECIPES.md
  • references/UI_INTERACTIONS.md
  • references/TEXT_ANIMATIONS.md
  • references/PHYSICS_PLUGINS.md
  • references/NEXTJS_REACT_PATTERNS.md
  • references/GSDEVTOOLS.md
  • references/DEBUG_CHECKLIST.md
请查看:
  • references/GSAP_CORE.md
  • references/GSAP_RECIPES.md
  • references/UI_INTERACTIONS.md
  • references/TEXT_ANIMATIONS.md
  • references/PHYSICS_PLUGINS.md
  • references/NEXTJS_REACT_PATTERNS.md
  • references/GSDEVTOOLS.md
  • references/DEBUG_CHECKLIST.md