关于 gsap
面向使用 GSAP 构建 JavaScript 动画的参考技能,涵盖核心动画模式、插件、React 用法及常见实现问题。
主要功能
- 01补间与时间轴模式
- 02滚动触发动画
- 03插件使用与注册
- 04React Hook 与清理
- 05常见问题及修复
适用场景
- 01编排界面动画
- 02随页面滚动触发元素动画
- 03为列表添加交错效果
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ noklip-io/ agent-skills --skill gsap安装后在 Claude Code 中输入/gsap确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdreferences/00-cheatsheet.md01-core.md02-easing.md03-timeline.md04-stagger.md05-utilities.md06-scrolltrigger.md07-scrollsmoother.md08-splittext.md09-svg-plugins.md10-flip.md11-react.md12-observer-draggable.md13-text-plugins.md详细介绍
GSAP 最佳实践
面向现代 Web 的专业级 JavaScript 动画库。提供高性能补间动画、强大的序列编排、基于滚动的动画以及丰富的插件生态系统。
安装
# Core library
npm install gsap
# React hook
npm install @gsap/react
# Register plugins (do once at app entry)
import gsap from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
gsap.registerPlugin(ScrollTrigger)
快速入门
import gsap from 'gsap'
// Basic tween
gsap.to('.box', { x: 200, duration: 1 })
// From animation
gsap.from('.box', { opacity: 0, y: 50, duration: 0.5 })
// Timeline sequence
const tl = gsap.timeline()
tl.to('.box1', { x: 100 })
.to('.box2', { x: 100 }, '-=0.5') // overlap by 0.5s
.to('.box3', { x: 100 }, '<') // same start as previous
核心概念
| 概念 | 说明 |
|---|---|
| 补间动画 | 在一段时间内改变属性的单个动画 |
| 时间轴 | 用于按顺序编排补间动画并进行精确控制的容器 |
| 缓动 | 控制动画的速度曲线(默认值:power1.out) |
| ScrollTrigger | 将动画与滚动位置关联起来 |
| 插件 | 为 GSAP 扩展专用功能 |
参考索引
| 参考资料 | 适用场景 |
|---|---|
references/00-cheatsheet.md | 快速参考,一览常见操作 |
references/01-core.md | 基本补间动画、特殊属性、回调、quickTo、ticker |
references/02-easing.md | 缓动函数、自定义缓动 |
references/03-timeline.md | 序列编排、定位、标签、嵌套 |
references/04-stagger.md | 错开动画、网格分布 |
references/05-utilities.md | 辅助函数(toArray、clamp、interpolate) |
references/06-scrolltrigger.md | 基于滚动的动画、固定、scrub、吸附 |
references/07-scrollsmoother.md | 平滑滚动、视差效果 |
references/08-splittext.md | 文本拆分与动画 |
references/09-svg-plugins.md | DrawSVG、MorphSVG、MotionPath |
references/10-flip.md | 布局动画(FLIP 技术) |
references/11-react.md | useGSAP Hook、清理、React 模式 |
references/12-observer-draggable.md | 手势检测、可拖动元素 |
references/13-text-plugins.md | TextPlugin、ScrambleTextPlugin |
常见模式
加载时淡入
gsap.from('.hero', {
opacity: 0,
y: 30,
duration: 1,
ease: 'power2.out'
})
错开显示列表动画
gsap.from('.list-item', {
opacity: 0,
y: 20,
stagger: 0.1,
duration: 0.5
})
滚动触发动画
gsap.registerPlugin(ScrollTrigger)
gsap.to('.box', {
x: 500,
scrollTrigger: {
trigger: '.box',
start: 'top 80%',
end: 'top 20%',
scrub: true
}
})
带控制项的时间轴
const tl = gsap.timeline({ paused: true })
tl.to('.modal', { opacity: 1, scale: 1, duration: 0.3 })
.from('.modal-content', { y: 20, opacity: 0 }, '-=0.1')
// Control playback
tl.play()
tl.reverse()
tl.progress(0.5)
需要避免的严重错误
1. 未注册插件
// ❌ Plugin won't work
import { ScrollTrigger } from 'gsap/ScrollTrigger'
gsap.to('.box', { scrollTrigger: { ... } })
// ✅ Register plugins first
gsap.registerPlugin(ScrollTrigger)
gsap.to('.box', { scrollTrigger: { ... } })
2. React 清理问题
// ❌ Memory leaks, zombie animations
useEffect(() => {
gsap.to('.box', { x: 100 })
}, [])
// ✅ Use useGSAP hook for automatic cleanup
import { useGSAP } from '@gsap/react'
useGSAP(() => {
gsap.to('.box', { x: 100 })
}, { scope: containerRef })
3. 补间动画冲突
// ❌ Two tweens fighting for same property
gsap.to('.box', { x: 100, duration: 2 })
gsap.to('.box', { x: 200, duration: 1 })
// ✅ Use overwrite or kill previous
gsap.to('.box', { x: 100, duration: 2, overwrite: true })
// or
gsap.killTweensOf('.box')
gsap.to('.box', { x: 200, duration: 1 })
4. ScrollTrigger 未刷新
// ❌ Layout changes but ScrollTrigger uses old positions
dynamicallyAddContent()
// ✅ Refresh after DOM/layout changes
dynamicallyAddContent()
ScrollTrigger.refresh()
5. 对不存在的元素进行动画处理
// ❌ Element not in DOM yet
gsap.to('.dynamic-element', { x: 100 })
// ✅ Wait for element or use immediateRender: false
gsap.to('.dynamic-element', {
x: 100,
immediateRender: false,
scrollTrigger: { ... }
})
6. from() 行为错误
// ❌ from() renders immediately, causing flash
gsap.from('.box', { opacity: 0 })
// ✅ Set initial state in CSS or use fromTo
// CSS: .box { opacity: 0; }
gsap.to('.box', { opacity: 1 })
// or use fromTo for explicit control
gsap.fromTo('.box', { opacity: 0 }, { opacity: 1 })
7. 忘记选择器作用域
// ❌ Affects ALL .box elements on page
gsap.to('.box', { x: 100 })
// ✅ Scope to container
gsap.to('.box', { x: 100 }, { scope: containerRef })
// or use gsap.utils.selector
const q = gsap.utils.selector(container)
gsap.to(q('.box'), { x: 100 })
快速参考
| 任务 | 解决方案 |
|---|---|
| 动画过渡到指定值 | gsap.to(target, { props }) |
| 动画从指定值开始 | gsap.from(target, { props }) |
| 双向动画 | gsap.fromTo(target, { from }, { to }) |
| 立即设置 | gsap.set(target, { props }) |
| 创建时间轴 | gsap.timeline({ options }) |
| 终止所有补间动画 | gsap.killTweensOf(target) |
| 全局默认值 | gsap.defaults({ ease, duration }) |
| 注册插件 | gsap.registerPlugin(Plugin) |
| 按 ID 获取 | gsap.getById('myTween') |
| 匹配媒体 | gsap.matchMedia() |
插件可用性
| 插件 | 许可 | 说明 |
|---|---|---|
| ScrollTrigger | 免费 | 基于滚动的动画 |
| Observer | 免费 | 手势/滚动检测 |
| Draggable | 免费 | 拖动交互 |
| Flip | 免费 | 布局动画 |
| TextPlugin | 免费 | 文本内容动画 |
| ScrollSmoother | Club | 平滑滚动 |
| SplitText | Club | 文本拆分 |
| DrawSVG | Club | SVG 描边动画 |
| MorphSVG | Club | SVG 变形 |
| MotionPath | Club | 基于路径的运动 |
| ScrollTo | 免费 | 滚动到指定位置 |
评论
支持 Markdown