SuperAPI AI 工具集

gsap

前端与建站

查看项目

更新于 10-14 17:53

技能介绍

用途

GSAP(GreenSock Animation Platform)是一个 JavaScript 动画引擎。本条目为其动画引擎子技能,主题为 core、timeline、ScrollTrigger 与 plugins。

何时使用 GSAP

资料提供了一张对比表,在 CSS Transitions、Framer Motion 与 GSAP 之间比较以下场景:

  • Hover / 简单切换:CSS 是,Framer Motion 是,GSAP 属于过度使用。
  • 序列化时间线:CSS 否,Framer Motion 有限,GSAP 是。
  • 滚动驱动:CSS 为 scroll-timeline,Framer Motion 有限,GSAP 为 ScrollTrigger。
  • 复杂交错(stagger):CSS 否,Framer Motion 基础,GSAP 为 distribution。
  • 移动端性能(60fps):CSS 良好,Framer Motion 一般,GSAP 优秀。
  • 文本拆分:CSS 否,Framer Motion 否,GSAP 为 SplitText。
  • SVG 形变 / 绘制:CSS 否,Framer Motion 否,GSAP 为 MorphSVG。
  • 包体积关注:CSS 0kb,Framer Motion 约 30kb,GSAP 约 25kb + 插件。

规则:如果动画需要时间线、滚动联动或分布式交错,使用 GSAP;否则优先使用 CSS。

使用方式

设置:始终在顶层注册插件。

import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { SplitText } from "gsap/SplitText";

gsap.registerPlugin(ScrollTrigger, SplitText);

React:使用 @gsap/react 包中的 useGSAP(),而不是 useEffect + 手动清理。

import { useGSAP } from "@gsap/react";

useGSAP(() => {
  gsap.to(".box", { x: 200 });
}, { scope: containerRef }); // auto-cleanup, auto-revert

核心模式

使用 defaults{} 避免重复:

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 获得完整控制:

gsap.fromTo(".card", { y: 40, opacity: 0 }, { y: 0, opacity: 1, stagger: 0.15 });

带分布的交错:

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)
  },
});

ScrollTrigger 模式

基础 Pin + Scrub:

gsap.to(".panel", {
  x: "-300%",
  ease: "none",
  scrollTrigger: {
    trigger: ".container",
    pin: true,
    scrub: 1,
    end: () => "+=" + document.querySelector(".container").scrollWidth,
  },
});

Batch 用于批量显现:

ScrollTrigger.batch(".card", {
  onEnter: (elements) => gsap.to(elements, { opacity: 1, y: 0, stagger: 0.1 }),
  start: "top 85%",
});

使用 containerAnimation 的水平滚动:

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,
  },
});

不要做 —— 关键错误

  1. 在 containerAnimation 上使用 ease
// 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 } });
  1. 在时间线的子 tween 上使用 ScrollTrigger
// 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 standalone
  1. 在 onUpdate 中 setState
// 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 React
  1. 时间线中 from() 的 immediateRender
// 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 });
  1. 动画非 transform 属性
// 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 transition

参考文件

  • references/core.md —— 完整的 gsap.to/from/fromTo/set API、选项
  • references/timeline.md —— Timeline、位置参数、嵌套
  • references/scrolltrigger.md —— 完整的 ScrollTrigger 参考
  • references/plugins.md —— SplitText、Flip、MorphSVG、DrawSVG、MotionPath、Observer

限制

本条目为动画引擎子技能,资料未提供收费、价格、平台支持范围、浏览器兼容细节或除上述内容外的更多约束,相关内容暂未提供。