GSAP Skills
Skills · 详解

八项官方技能详解

每个技能讲清三件事:它是什么、何时用、怎么用。vanilla 类技能全部配了可交互现场样例,React / Vue 类给出官方推荐写法。

01

gsap-core核心 API 与基础补间

它是什么

GSAP 引擎的核心技能:gsap.to() / from() / fromTo() 三种补间方法、缓动、时长、stagger、默认值,以及面向响应式与无障碍的 gsap.matchMedia()。这是所有其他技能的地基。

何时用

  • 单元素/多元素基础动画(移动、旋转、缩放、淡入淡出)
  • 需要运行时控制(暂停、反转、跳到某个进度)
  • 需要精确缓动曲线,或按序列/交错编排

关键 API

gsap.to(".box", { x: 100, rotation: 360,
  duration: 0.8, ease: "power2.inOut" });

gsap.from(el, { autoAlpha: 0, y: 20, stagger: 0.1 });
gsap.fromTo(el, { x: 0 }, { x: 200, duration: 1 });

官方最佳实践

  • 属性一律用 camelCase;移动优先用 transform 别名(x / y / scale / rotation)
  • 淡入淡出用 autoAlpha(为 0 时自动隐藏、不挡点击)
  • 用 gsap.matchMedia() 处理断点与 prefers-reduced-motion

相关

timelinescrolltriggerutils
SAMPLE · EASING

五种缓动对比

同一段位移,换不同 ease 手感完全不同。点击重播,观察谁先冲出、谁带回弹。

gsap.to(el, { x: 180, duration: 0.9,
  ease: "back.out(1.7)" }); // 各自不同 ease
power1.out · power3.inOut · back · elastic · expo
SAMPLE · FUNCTION VALUES

函数化取值

vars 里传函数,GSAP 会为每个目标单独求值一次——按序号递增位移就是这么写的。

gsap.to(items, {
  x: (i) => i * 26,          // 每个目标单独求值
  y: (i) => i % 2 ? -14 : 14,
  stagger: 0.06, duration: 0.5
});
i 为目标序号,从 0 开始
02

gsap-timeline序列编排与播放控制

它是什么

时间线把多个补间按顺序(或指定时刻)编排成一条可整体控制的动画线,替代"链式 delay"的官方做法。支持 position 参数、标签、嵌套与暂停/播放/反转。

何时用

  • 多步骤动画需要严格排序、重叠或精确对齐
  • 整条动画需要统一控制(播放、反转、跳到某时刻)
  • 与 ScrollTrigger 配合做滚动驱动的时间线

关键 API

const tl = gsap.timeline({ defaults: { duration: 0.5, ease: "power2.out" } });
tl.to(a, { x: 100 })                 // 依序追加
  .to(b, { y: 50 }, "<0.2")        // 在上一段开始后 0.2s
  .to(c, { opacity: 0 }, "-=0.1");   // 提前 0.1s 收尾
tl.pause(); tl.play(); tl.reverse(); tl.restart();

官方最佳实践

  • 用 position 参数精确控制各步时刻,别用 delay 硬排
  • 把公共 duration / ease 放进 defaults,子补间自动继承
  • 多步用 labels 标注关键节点,代码可读可维护

相关

corescrolltrigger
SAMPLE · PLAYBACK

播放控制面板

三步时间线(平移 → 变色 → 缩放)。试试播放、暂停、倒退、重播四条控制。

const tl = gsap.timeline({ defaults: { duration: 0.5 } });
tl.to(box, { x: 170, duration: 0.7 })
  .to(box, { backgroundColor: "#7CF9AB" })
  .to(box, { scale: 0.55 }, "+=0.1");
tl.pause(); tl.play(); tl.reverse(); tl.restart();
SAMPLE · POSITION

position 参数

A 先走;B 用 <0.2 在 A 开始 0.2s 后并行;C 用默认 > 等 A 结束再动。

const tl = gsap.timeline();
tl.to(a, { x: 150, duration: 0.8 })   // A 起点
  .to(b, { x: 150 }, "<0.2")   // A 开始后 0.2s
  .to(c, { x: 150 });            // 默认 ">":A 结束后
B 与 A 并行、C 紧随其后
03

gsap-scrolltrigger滚动联动、固定与跟手

它是什么

把动画与滚动位置绑定的技能:元素进入视口触发、pin 固定区块、scrub 让进度跟手、batch 批量入场、toggleActions 控制进出行为。

何时用

  • 滚动驱动的叙事:滚到某处动画播放/反向
  • 长页面的固定区块(pin)或视差/进度条
  • 批量元素入场(列表、卡片、网格)

关键 API

gsap.to(el, { x: 300,
  scrollTrigger: {
    trigger: el, start: "top center",
    end: "bottom center",
    toggleActions: "play reverse play reverse",
    scrub: 1            // 或 true:进度跟手
  }
});

官方最佳实践

  • gsap.registerPlugin(ScrollTrigger) 只用注册一次
  • ScrollTrigger 只挂时间线或顶层补间,别挂子补间
  • scrub 与 toggleActions 二选一,别同时用
  • 布局变化后调用 ScrollTrigger.refresh()

相关

coretimeline
SAMPLE · PIN

固定区块(pin)

继续向下滚动:舞台被固定在视口内,进度条随滚动填充,数字实时跟手。

0%
ScrollTrigger.create({
  trigger: stage, start: "top top",
  end: "+=500", pin: true, scrub: 1,
  onUpdate: (self) => {
    num.textContent = Math.round(self.progress * 100) + "%";
  }
});
向下滚动体验 · pin + scrub
SAMPLE · TOGGLE

进出反向(toggleActions)

方块进入视口时播放,离开时反向回退——常用于"进入才现身"的内容。

gsap.to(box, {
  x: 200, rotation: 180,
  scrollTrigger: {
    trigger: stage, start: "top 70%",
    toggleActions: "play none none reverse"
  }
});
滚上滚下试试进出行为
04

gsap-plugins布局翻转、拖拽与文本/SVG 特效

它是什么

GSAP 插件生态的总入口:Flip(布局翻转)、Draggable(拖拽)、ScrollTo / ScrollSmoother(滚动)、SplitText / ScrambleText(文本)、DrawSVG / MorphSVG / MotionPath(SVG)、CustomEase(自定义缓动)、Physics2D(物理)等。自 Webflow 收购起全部插件免费,无需会员与注册。

何时用

  • 布局状态切换(列表重排、网格展开折叠)→ Flip
  • 拖拽 / 滑块 / 可重排列表 → Draggable
  • 逐字逐词文本动画、描边绘制、形状形变 → SplitText / DrawSVG / MorphSVG

关键 API

gsap.registerPlugin(Flip, Draggable);

const state = Flip.getState(".item");
// 改变 DOM(重排 / 增删 / 换 class)
Flip.from(state, { duration: 0.5, ease: "power2.inOut" });

Draggable.create(".knob", { type: "x", bounds: "#stage", inertia: true });

官方最佳实践

  • 每个插件使用前都 gsap.registerPlugin() 注册
  • Flip 三步骤:getState → 改 DOM → from
  • 组件卸载时 revert 插件实例(如 SplitText.revert())

相关

corescrolltrigger
SAMPLE · FLIP

布局翻转动画

记录状态 → 打乱 DOM → Flip 平滑补间。还原同理,全程无手工坐标。

1
2
3
4
5
6
7
8
const state = Flip.getState(items);
// 改 DOM:打乱顺序
shuffle(items) // items.forEach(...) 重新 append
Flip.from(state, { duration: 0.5, ease: "power2.inOut" });
SAMPLE · DRAGGABLE

拖拽 + 边界约束

方块可在舞台内任意拖动,碰到边界有回弹阻力(edgeResistance)。

拖我
Draggable.create(box, {
  type: "x,y",
  bounds: stage,          // 限制在舞台内
  edgeResistance: 0.7     // 边界回弹阻力
});
鼠标 / 触屏均可拖动
05

gsap-utils数学与数组工具函数

它是什么

一组纯函数:clamp(夹取)、mapRange(区间映射)、normalize / interpolate(归一化 / 插值)、random / snap / shuffle(随机 / 吸附 / 打乱)、wrap(循环取值)、toArray / selector / pipe(集合处理)。无需注册,直接 gsap.utils.xxx()。

何时用

  • 把滑块 / 滚动进度映射成动画值(mapRange)
  • 把数值夹在安全区间、吸附到网格(clamp / snap)
  • 随机取值或按函数式值写进 tween vars

关键 API

gsap.utils.clamp(0, 100, 150);              // 100
gsap.utils.mapRange(0, 100, 0, 260, 50);    // 130
gsap.utils.interpolate("#0AE448", "#7CF9AB", 0.5);
gsap.utils.random(-100, 100);               // 随机数
const map = gsap.utils.mapRange(0, 1, 0, 360); // 省略取值 = 返回函数

官方最佳实践

  • 同样的映射/夹取多用时,省略最后一个参数拿可复用函数
  • random 想要可复用函数,末尾传 true(唯一例外)
  • mapRange / normalize 只处理数字,带单位用 getUnit / unitize

相关

corescrolltrigger
SAMPLE · MAPRANGE

滑块驱动动画

拖动滑块:mapRange 把 0–100 映射成位移,interpolate 在两种颜色间插值。

0
const x = gsap.utils.mapRange(0, 100, 0, 260, v);
const color = gsap.utils.interpolate("#0AE448", "#7CF9AB", v / 100);
gsap.set(box, { x, backgroundColor: color });
原生 range 输入,即时映射
SAMPLE · RANDOM

随机变换

每次点击,六个方块各自随机位移、旋转与颜色——全部由 gsap.utils.random 生成。

gsap.to(items, {
  x: gsap.utils.random(-60, 60),
  rotation: gsap.utils.random(-180, 180),
  backgroundColor: gsap.utils.random(["#0AE448", "#7CF9AB", "#3A7D50"]),
  duration: 0.6, stagger: 0.05, overwrite: true
});
每次结果都不同
06

gsap-reactuseGSAP 钩子与组件生命周期

它是什么

React / Next.js 中正确使用 GSAP 的官方模式:优先 @gsap/react 的 useGSAP 钩子,配合 scope 限定选择器、contextSafe 包裹回调,卸载时自动 revert 全部动画与 ScrollTrigger。

何时用

  • React 组件里做任何 GSAP 动画
  • 需要避免卸载后动画泄漏、报错(React 18 StrictMode 双执行)
  • Next.js SSR 场景——GSAP 只允许在客户端跑

关键模式

  • 目标用 ref,选择器必须有 scope
  • 不用 useGSAP 时:useEffect + gsap.context,cleanup 里 ctx.revert()
  • 事件回调里新建动画用 contextSafe 包裹
  • SSR:所有 gsap.* 调用只出现在 useEffect / useGSAP 内

相关

coretimelineframeworks
OFFICIAL PATTERN

useGSAP:挂载创建、卸载自动清理

这是官方推荐写法(需在 React 工程中运行,纯静态页无法现场执行)。scope 保证选择器只匹配组件内部。

import { useGSAP } from "@gsap/react";
gsap.registerPlugin(useGSAP);          // 应用入口注册一次

const containerRef = useRef(null);

useGSAP(() => {
  gsap.to(".box", { x: 100 });
  gsap.from(".item", { autoAlpha: 0, y: 20, stagger: 0.1 });
}, { scope: containerRef });           // 选择器只匹配组件内部
scoperef 或元素作作用域,".box" 不会误伤组件外的同名元素
自动清理卸载时 revert 动画与 ScrollTrigger,不留泄漏、兼容 StrictMode
contextSafe事件回调里创建的动画用它包裹,卸载后安全 no-op
SSR 安全useGSAP 只在客户端执行;服务端渲染期间不碰 gsap.*
07

gsap-performance60fps 的动画写法

它是什么

让动画保持流畅的性能指南:只动 transform 与 opacity(交给合成器、跳过布局)、用 stagger 批量而非逐条 delay、高频更新用 gsap.quickTo() 复用单个 tween、适时清理离屏动画。

何时用

  • 动画掉帧、低端设备卡顿时排查
  • 大量元素同时动画(列表、网格、粒子)
  • 鼠标跟随、滚动绑定这类高频触发场景

关键做法

  • 移动用 x / y,别用 top / left / width / height
  • 动画元素加 will-change: transform,但别全站乱加
  • 高频属性更新用 gsap.quickTo()
  • 布局变化后按需 ScrollTrigger.refresh()(防抖)

相关

corescrolltrigger
SAMPLE · BATCH

120 元素批量动画

一个 tween + stagger 驱动 120 个方块,全部只动 transform 属性——即使量大也保持流畅。

点击「运行」生成并动画 120 个方块
gsap.to(".mini", {                 // 120 个目标,一条 tween
  x: "random(-14, 14)", rotation: "random(-120, 120)",
  duration: 1.2, ease: "power1.inOut",
  stagger: { each: 0.006 }
});                              // 只动 transform,不触发布局
SAMPLE · QUICKTO

鼠标平滑跟随

高频 mousemove 下,quickTo 复用同一个 tween,只更新目标值——比每帧新建 tween 高效得多。

在区域内移动鼠标,圆点平滑跟随
const xTo = gsap.quickTo(dot, "x", { duration: 0.4, ease: "power3" });
const yTo = gsap.quickTo(dot, "y", { duration: 0.4, ease: "power3" });
stage.addEventListener("mousemove", e => {
  xTo(e.offsetX - 10); yTo(e.offsetY - 10);   // 每帧只改目标值
});
桌面端体验最佳
08

gsap-frameworksVue / Svelte / Nuxt 集成

它是什么

Vue、Svelte、Nuxt 等非 React 框架中集成 GSAP 的官方模式。三条铁律:DOM 就绪后创建(onMounted / onMount)、卸载时清理(ctx.revert())、选择器限定作用域(gsap.context(scope))。

何时用

  • Vue 3(组合式 API 或 script setup)组件动画
  • Svelte / SvelteKit 组件动画
  • Nuxt 4 需要懒加载插件、SSR 安全的场景

关键做法

  • onMounted 里 gsap.context(回调, 容器 ref)
  • onUnmounted / onMount 返回函数里 ctx.revert()
  • 插件在应用入口注册一次;不常用的插件懒加载(官方 Nuxt composable)

相关

corereactscrolltrigger
OFFICIAL PATTERN

Vue 3 + Svelte:生命周期与清理

官方推荐写法(需在对应框架工程中运行)。仓库内 examples/vue、examples/nuxt 有可运行工程。

// Vue 3(组合式 API)
import { onMounted, onUnmounted, ref } from "vue";
const container = ref(null);
let ctx;
onMounted(() => {
  ctx = gsap.context(() => {
    gsap.to(".box", { x: 100 });
    gsap.from(".item", { autoAlpha: 0, y: 20, stagger: 0.1 });
  }, container.value);              // 作用域:只匹配组件内
});
onUnmounted(() => ctx?.revert());  // 卸载清理

// Svelte
onMount(() => {
  const ctx = gsap.context(() => gsap.to(".box", { x: 100 }), container);
  return () => ctx.revert();        // onMount 返回清理函数
});
gsap.context(scope)选择器只在组件子树内匹配,避免跨组件误伤
卸载 revert动画与 ScrollTrigger 全部杀掉、内联样式还原,不留泄漏
插件注册一次应用入口注册;懒加载不常用插件减小首包
Nuxt 4官方 useGSAP 组合式函数 + lazyLoadPlugin 已内置在 examples/nuxt