mcpField
G
gsap

gsap

github.com/athevon设计与 UI705995 次安装3 周前更新
代码仓库

关于 gsap

面向 Web 动效开发者的 GSAP 技能,讲解时间轴、滚动触发、错列动画和 React 集成。内容还涵盖常见实现陷阱与性能注意事项。

主要功能

  1. 01时间轴动画编排
  2. 02ScrollTrigger 滚动动画
  3. 03错列与分布式动画
  4. 04React useGSAP 集成
  5. 05动画实现陷阱说明

适用场景

  1. 01制作连续的多元素动画
  2. 02构建滚动驱动的页面效果
  3. 03在 React 中管理动画清理

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/athevon/genjutsu --skill gsap

安装后在 Claude Code 中输入/gsap确认已加载。

详细介绍

版本敏感。 以下每个 API 名称、SDK 门槛和浏览器支持声明均已于 2026-09-08 对照一手来源核实。核实依据和时间见 _jutsu/VERSIONS.md。如果该日期已久远,请在依据版本号采取行动前重新核实。

GSAP - 动画引擎

GSAP 3.15(于 2026 年 4 月 13 日发布)。自 3.13 起,整个库——包括所有曾经的 Club 插件(SplitText、MorphSVG、DrawSVG、ScrollSmoother、InertiaPlugin、MotionPathHelper、CustomEase 等)——均包含在公开的 gsap npm 包中,并且免费,包含商业用途,遵循 GreenSock Standard「无需付费」许可。没有 Club 付费墙。 GreenSock 还发布了官方 Agent 技能(MIT,8 项技能:core、timeline、scrolltrigger、plugins、utils、react、performance、frameworks):https://github.com/greensock/gsap-skills ——值得与此子技能一同安装。

何时使用 GSAP

标准CSS 过渡Framer MotionGSAP
悬停 / 简单切换是是杀鸡用牛刀
序列时间轴否有限是
滚动驱动scroll-timeline有限ScrollTrigger
复杂交错否基础Distribution
移动端性能(60fps)良好一般极佳
文本拆分否否SplitText
SVG 变形 / 绘制否否MorphSVG
包体积顾虑0kb~30kb~25kb + 插件

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

设置

// Always register plugins at the top level
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 模式

基本固定 + 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 } });
2. 在时间轴中的子补间上使用 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
3. 在 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
4. 在时间轴中的 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 });
5. 为非 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 - 时间轴、位置参数、嵌套
  • references/scrolltrigger.md - 完整的 ScrollTrigger 参考
  • references/plugins.md - SplitText、Flip、MorphSVG、DrawSVG、MotionPath、Observer

评论

支持 Markdown