GSAP动画速查表:核心方法、属性与实战技巧全解析
1. 为什么你需要一份GSAP速查表?
如果你正在做网页动画,无论是简单的按钮悬停效果,还是复杂的交互式叙事页面,GSAP(GreenSock Animation Platform)这个名字你大概率绕不过去。它被无数前端开发者誉为“动画界的瑞士军刀”,功能强大到令人惊叹,但随之而来的,是它那庞大且仍在不断增长的API体系。
我刚开始接触GSAP时,面对官方文档里琳琅满目的方法、属性、缓动曲线和插件,经常陷入一种“我知道它能做,但具体用哪个方法、参数怎么写来着?”的窘境。尤其是在项目紧张、需要快速实现某个效果时,反复翻查英文文档,或者去Stack Overflow上找代码片段,效率实在太低。更别提那些细微但关键的语法差异,比如.to()、.from()、.fromTo()的传参区别,duration和delay的单位,stagger的多种配置方式……这些细节,看一遍文档容易忘,用的时候又必须精确。
这就是一份好的速查表(Cheatsheet)的价值所在。它不是用来系统学习的教程,而是你熟练工手边的“扳手和螺丝刀”,在你明确知道要“拧哪个螺丝”时,能让你瞬间找到对的工具,并以正确的姿势使用它。而一份汉化版的速查表,更是消除了语言隔阂,让你在思考“技术实现”时,无需额外分心去处理“语言理解”,思维更加流畅。
今天这份GSAP速查表,就是我基于多年使用经验,结合官方文档和社区最佳实践,为你整理的一份“实战工具箱”。它不会教你GSAP的哲学,但能确保你在需要时,快速、准确地写出能运行的动画代码。我们直接从最核心、最常用的部分开始。
2. GSAP核心(GSAP Core)方法速查
GSAP的核心动画功能主要由几个方法(Method)来驱动,它们是使用频率最高的部分,必须烂熟于心。
2.1 创建动画的基本方法:gsap.to(),gsap.from(),gsap.fromTo()
这是GSAP的基石,绝大多数动画都由它们创建。
gsap.to(target, vars)
- 功能:将目标元素从当前状态动画到指定状态。
- 核心参数:
target: 目标,可以是CSS选择器字符串(如"#box")、DOM元素、元素数组,甚至是普通对象。vars: 一个配置对象,描述动画的终点状态和选项。
- 代码示例与解析:
为什么用// 将一个id为“box”的div,用1秒时间,移动到x坐标为300的位置,并使用“power2.out”缓动函数 gsap.to("#box", { x: 300, // 变换属性:横向移动300像素 duration: 1, // 持续时间:1秒 ease: "power2.out" // 缓动函数:先快后慢 });.to()?当你明确知道元素的起点(通常是其初始样式或位置),并想让它变化到某个新状态时,就用.to()。这是最直观的“移动到”动画。
gsap.from(target, vars)
- 功能:将目标元素从指定状态动画到当前状态。可以理解为“从某个状态出现”的动画。
- 代码示例与解析:
为什么用// 让一个元素从屏幕外(x: -100)飞入到其原本位置(x: 0) gsap.from(".item", { x: -100, // 起点:从左侧100像素外开始 opacity: 0, // 起点:完全透明 duration: 0.8, stagger: 0.2 // 错开:每个.item元素依次开始动画,间隔0.2秒 });.from()?非常适合做入场动画。你无需知道元素最终在哪,只需定义它“从哪来”。常用于页面加载时元素的飞入、淡入效果。
gsap.fromTo(target, fromVars, toVars)
- 功能:完全控制动画的起点和终点状态。
- 核心参数:需要两个配置对象,第一个 (
fromVars) 定义起点,第二个 (toVars) 定义终点和动画选项。 - 代码示例与解析:
为什么用// 将一个元素从完全透明、放大状态,动画到完全不透明、正常大小,并旋转一圈 gsap.fromTo("#circle", { // fromVars: 起点状态 scale: 2, opacity: 0, rotation: 0 }, { // toVars: 终点状态和选项 scale: 1, opacity: 1, rotation: 360, duration: 1.5, ease: "back.out(1.7)" // 带“回弹”效果的缓动 } );.fromTo()?当你需要精确控制动画的起始和结束的每一帧属性时使用。.to()和.from()都是它的特例。当动画逻辑不是简单的“从当前到某处”或“从某处到当前”时,它是最佳选择。
实操心得:很多新手会混淆
.from()和.to()。一个简单的记忆方法是:gsap.to(元素, {终点状态});gsap.from(元素, {起点状态})。思考动画的“驱动方向”是从状态A到状态B,还是从状态B到状态A。
2.2 动画控制与时间轴:gsap.timeline()
单个动画很简单,但现实项目中的动画往往是连续的、交织的。直接嵌套回调或者设置复杂的delay会让代码变成“回调地狱”,难以维护。gsap.timeline()就是来解决这个问题的。
gsap.timeline(vars)
- 功能:创建一个时间轴实例,用于编排多个动画,形成序列或并行关系。
- 核心优势:自动管理动画间的先后顺序,无需手动计算
delay;可以通过位置参数(Position Parameter)灵活调整动画插入点。 - 代码示例与解析:
位置参数详解:// 创建一个时间轴 let tl = gsap.timeline({ defaults: { // 时间轴内所有动画的默认配置 duration: 0.5, ease: "power2.inOut" } }); // 添加动画到时间轴 tl.to("#box1", { x: 200 }) // 动画1:立即开始 .to("#box2", { y: 100 }, "<") // 动画2:与动画1同时开始(“<”表示在上一个动画开始时插入) .to("#box3", { rotation: 180 }, "+=0.5") // 动画3:在动画2结束后0.5秒开始 .from("#box4", { opacity: 0 }, "-=0.2"); // 动画4:在动画3结束前0.2秒开始 // 控制整个时间轴 tl.pause(); tl.resume(); tl.seek(1.5); // 跳转到1.5秒处 tl.reverse();- 绝对时间:
1(第1秒),"2.5"(第2.5秒)。 - 相对偏移:
"+=1"(上一个动画结束后1秒),"-=0.5"(上一个动画结束前0.5秒)。 - 标签:
"labelName"(插入到该标签处),"labelName+=0.3"(标签后0.3秒)。 <和>:"<"(与上一个动画同时开始),">"(与上一个动画同时结束),还可以组合如"<0.2"(比上一个动画晚0.2秒开始)。
- 绝对时间:
踩坑提醒:时间轴的
defaults配置非常有用,能极大简化代码。但注意,如果某个动画显式设置了与defaults相同的属性(如duration),则会覆盖默认值。另外,复杂的时间轴建议多用addLabel()添加标签,用标签来管理插入点,代码可读性会高很多。
3. 动画属性(Properties)与特殊属性(Special Properties)速查
在vars对象里,你可以设置两类属性:一类是你要动画的目标属性(如x,opacity),另一类是控制动画行为的特殊属性(如duration,ease)。
3.1 常见动画目标属性
GSAP可以动画任何数值属性,包括CSS属性和自定义对象属性。
| 属性分类 | 属性示例 | 说明 | GSAP特性 |
|---|---|---|---|
| 变换(Transforms) | x,y,z | 横向/纵向/深度位移(像素)。优于CSS的translateX/Y,因为性能更好且无需单位。 | x: 100即向右移动100px。支持xPercent,yPercent进行百分比移动。 |
rotation,rotationX,rotationY | 旋转(角度)。 | rotation: 360旋转一圈。 | |
scale,scaleX,scaleY | 缩放。 | scale: 1.5放大1.5倍。 | |
skewX,skewY | 倾斜(角度)。 | ||
| CSS属性 | opacity | 透明度。 | 值 0~1。 |
width,height | 宽高。 | 需带单位,如width: "200px",height: "50%"。 | |
backgroundColor,color | 颜色。 | 支持所有CSS颜色格式。 | |
borderRadius | 圆角。 | 如borderRadius: "50%"。 | |
| SVG属性 | attr | 动画SVG属性,如stroke-dasharray,viewBox。 | 需使用attr: { stroke-dashoffset: 100 }格式。 |
drawSVG | (DrawSVG插件)SVG路径绘制动画。 | 神器,用于线条描边效果。 | |
| 自定义属性 | 任何对象属性 | 动画任意对象的任意数值属性。 | gsap.to(obj, { myCustomProp: 100 }) |
性能核心要点:始终优先使用GSAP的变换属性(
x,y,rotation)而非对应的CSS属性(left,top,transform: rotate())。原因是GSAP的变换属性会智能地合并到CSStransform矩阵中,浏览器只需重绘(repaint),无需重排(reflow),性能极高。而动画left/top会触发昂贵的重排。
3.2 关键特殊属性(Special Properties)
这些属性不改变元素状态,而是控制动画如何执行。
| 属性 | 类型 | 默认值 | 说明与示例 |
|---|---|---|---|
duration | Number | 0.5 | 动画持续时间(秒)。duration: 1表示1秒。 |
delay | Number | 0 | 动画开始前的延迟(秒)。delay: 0.5表示等待0.5秒后开始。 |
ease | String | "power1.out" | 缓动函数,动画的灵魂。定义动画过程中的加速度变化。 |
repeat | Number | 0 | 重复次数。-1表示无限循环。repeat: 2动画共播放3次(1次原始+2次重复)。 |
yoyo | Boolean | false | 布尔值。如果为true,每次重复播放时会反向进行(像悠悠球一样)。需与repeat配合使用。 |
stagger | Number/Object | - | 错开动画,为多个目标设置动画开始时间偏移。 |
onComplete | Function | - | 动画完成时的回调函数。onComplete: () => console.log("done!") |
onStart | Function | - | 动画开始时的回调函数。 |
onUpdate | Function | - | 动画每次更新(每帧)时的回调函数,参数是动画实例本身。 |
paused | Boolean | false | 如果为true,动画创建后立即暂停,需要手动调用.play()。 |
3.3 缓动(Ease)函数速查
ease属性极大地影响动画的“感觉”。GSAP内置了丰富的缓动类型。
| 缓动类型 | 格式示例 | 视觉感受 | 适用场景 |
|---|---|---|---|
| Power | "power1.in","power2.out","power3.inOut" | 指数级加速/减速。数字越大(1,2,3,4),惯性越强。 | 最常用,模拟自然运动。power2.out适合物体移动停止。 |
| Back | "back.in(1.5)","back.out" | 带“回弹”或“过冲”效果。参数控制过冲量。 | 夸张的、有弹性的效果,如对话框弹出。 |
| Elastic | "elastic.out(1, 0.3)" | 弹性振动效果。参数控制振幅和周期。 | 弹簧、果冻般的抖动效果。 |
| Bounce | "bounce.out" | 像皮球落地弹跳的效果。 | 欢快、卡通化的效果。 |
| Circ / Expo / Sine | "circ.inOut","expo.out" | 不同的数学曲线,提供细微的加速差异。expo开始极慢,结束极快。 | 需要特定精密运动曲线时。 |
| Stepped | "steps(12)" | 阶梯式动画,非连续。参数是步数。 | 制作逐帧动画或复古游戏效果。 |
| CustomEase | (需插件) | 通过可视化编辑器或贝塞尔曲线自定义任何缓动。 | 品牌动画或需要与设计稿曲线完全匹配时。 |
经验之谈:不要只会用
"linear"(线性)或默认缓动。花点时间在 GSAP Ease Visualizer 上感受不同缓动的区别。一个经验法则是:入场动画(元素出现)常用.in或.inOut,强调“启动感”;退场动画(元素消失)常用.out,强调“结束感”。例如,一个模态框弹出,用"back.out(1.2)"会比"power2.out"更有冲击力。
3.4 错开(Stagger)动画详解
stagger是制作列表、网格动画的神器,能让多个元素的动画依次进行,产生波浪或序列效果。
基础数值用法:
// 每个“.item”元素依次动画,间隔0.1秒 gsap.to(".item", { y: 50, stagger: 0.1 // 每个动画间隔0.1秒 });高级对象配置:
gsap.from(".grid-cell", { scale: 0, opacity: 0, duration: 0.5, stagger: { amount: 1.5, // 整个错开过程的总时间为1.5秒 from: "center", // 从中心向四周扩散 (“start”, “end”, “edges”, “random”) grid: [5, 5], // 指定网格布局为5行5列,按网格顺序错开 ease: "power2.inOut", // 错开间隔本身的缓动 repeat: -1, // 每个元素的动画重复(需元素本身有repeat) yoyo: true } });为什么stagger如此重要?因为它将一组元素的动画从“同时发生”变成了“有组织的序列”,这符合人类的视觉认知习惯,能极大地提升界面的高级感和引导性。在卡片列表加载、导航菜单展开等场景中几乎是必用项。
4. 核心控制方法与插件概览
创建了动画,你还需要能控制它。GSAP提供了精细的控制方法。
4.1 动画实例控制方法
每个gsap.to(),.from(),.fromTo()或timeline()调用都会返回一个动画或时间轴实例,你可以用它进行控制。
let tween = gsap.to("#el", { x: 100, duration: 1, paused: true }); // 创建时暂停 // 基础控制 tween.play(); // 播放 tween.pause(); // 暂停 tween.resume(); // 从暂停处继续播放 tween.reverse(); // 反向播放 tween.restart(); // 重新开始(跳转到开头并播放) tween.seek(0.5); // 跳转到动画的0.5秒处 tween.progress(0.75); // 跳转到动画进度的75%处(0到1之间) tween.kill(); // 立即停止并销毁动画,释放资源 // 获取状态 console.log(tween.progress()); // 获取当前进度(0-1) console.log(tween.time()); // 获取当前时间(秒) console.log(tween.isActive()); // 动画是否正在播放4.2 常用插件简介(按需引入)
GSAP的核心库非常轻量,更多强大功能通过插件实现。你需要额外引入插件文件(如gsap.min.js+ScrollTrigger.min.js)。
| 插件名 | 用途 | 核心概念/API示例 |
|---|---|---|
| ScrollTrigger | 滚动驱动动画。将动画与滚动位置绑定。 | scrollTrigger: { trigger: "#section1", start: "top center", end: "bottom top", scrub: true, pin: true } |
| TextPlugin | 文字逐字打印、模糊显现等效果。 | gsap.to(".text", { duration: 2, text: "这是新文字" }) |
| MorphSVGPlugin | 将SVG图形平滑地变形为另一个SVG图形。 | MorphSVGPlugin.convertToPath("#circle"); gsap.to("#shape", {morphSVG: "#newShape"}); |
| DrawSVGPlugin | SVG线条的绘制与擦除动画。 | gsap.fromTo("#path", {drawSVG: "0%"}, {drawSVG: "100%", duration: 2}) |
| MotionPathPlugin | 让元素沿SVG路径或自定义路径运动。 | gsap.to("#plane", {duration: 5, motionPath: {path: "#path", align: "#path"}}) |
| EaselPlugin / PixiPlugin | 与EaselJS / PixiJS库集成,动画其显示对象属性。 | 用于Canvas/WebGL动画。 |
插件使用须知:使用前务必用
gsap.registerPlugin(ScrollTrigger, TextPlugin, ...)注册插件。对于ScrollTrigger这类重量级插件,要特别注意性能,避免在大量元素上创建复杂的滚动触发器,并适时使用scrollTrigger.kill()或scrollTrigger.refresh()进行管理。
5. 实战技巧与常见问题排查
掌握了上面的“武器库”,我们来看看如何在实际项目中组合使用,并避开那些常见的坑。
5.1 性能优化黄金法则
- 优先使用
x,y而非top,left:如前所述,这是最重要的性能准则。transform和opacity是仅触发合成(composite)的属性,性能开销最小。 - 使用
will-change或translateZ(0)谨慎:现代浏览器通常能自动优化。过度使用will-change: transform反而可能消耗更多内存。仅在遇到性能问题(如动画卡顿)时,对运动元素尝试添加。 - 减少布局抖动(Layout Thrashing):避免在动画进行中(如在
onUpdate回调里)频繁读取会触发重排的样式(如offsetWidth,scrollTop)。如果必须读取,使用gsap.ticker或requestAnimationFrame进行节流。 - 对复杂动画使用
timeScale():timeline.timeScale(2)可以让整个时间轴以2倍速播放,这比调整每个动画的duration更高效。 - 及时清理:对于不再需要的动画(如页面离开),调用
.kill()方法,尤其是解绑ScrollTrigger事件 (scrollTrigger.kill())。
5.2 响应式设计中的GSAP
动画如何适配不同屏幕尺寸?硬编码像素值(如x: 500)会出问题。
解决方案1:使用函数或相对值
// 使用函数动态计算值 gsap.to("#box", { x: () => window.innerWidth / 2, // 移动到屏幕中间 duration: 1 }); // 使用百分比或vw/vh单位(GSAP 3支持) gsap.to("#box", { x: "50vw", // 移动到视口宽度的50% y: "30%" // 移动到父元素高度的30% });解决方案2:响应式重置与匹配媒体查询
// 创建动画引用 let mm = gsap.matchMedia(); let tween; // 定义不同断点下的动画 mm.add("(min-width: 768px)", () => { // 桌面端动画 tween = gsap.to("#box", { x: 300, rotation: 360 }); return () => { tween.kill(); }; // 清理函数,当离开此断点时执行 }); mm.add("(max-width: 767px)", () => { // 移动端动画 tween = gsap.to("#box", { x: 100, rotation: 180 }); return () => { tween.kill(); }; });gsap.matchMedia()是处理响应式动画的终极武器,它能自动监听窗口变化,并在断点改变时清理旧动画、创建新动画。
5.3 常见报错与排查
gsap.to(...) is not a function:最常见原因——没有正确引入GSAP库。检查<script>标签路径,并确保在调用GSAP代码之前已加载。- 动画不执行或瞬间完成:
- 检查
duration是否设置为0。 - 检查目标元素是否存在、选择器是否正确。用
console.log(document.querySelector(“yourSelector”))验证。 - 检查是否意外将动画设置为
paused: true。
- 检查
stagger效果不符合预期:检查stagger的值是数字还是对象。如果目标是单个元素,stagger无效。确保选择器选中的是多个元素。- ScrollTrigger 不触发:
- 检查
trigger元素是否在DOM中且可见。 - 检查
start和end的参考点(如"top bottom")是否逻辑正确。 - 检查滚动容器是否为
body/html,如果是自定义滚动容器,需设置scroller属性。 - 在页面所有资源(如图片)加载后,手动调用一次
ScrollTrigger.refresh()。
- 检查
- 动画结束后元素“跳回”原状:这通常是因为GSAP动画是增量的。例如,你点击按钮执行
gsap.to(el, {x: 100}),每次点击都会从当前值增加100px。如果需要绝对定位,使用.set()先重置,或使用.fromTo()明确起终点。
5.4 一个综合实战案例:交互式卡片流
假设我们有一个卡片列表,要求:1. 页面加载时卡片依次淡入上浮。2. 鼠标悬停时卡片轻微放大并有阴影。3. 点击卡片时,卡片放大至全屏并显示详情。
// 1. 初始化卡片位置并创建入场时间轴 gsap.set(".card", { y: 30, opacity: 0 }); // 初始状态:在下,透明 let cardTl = gsap.timeline(); cardTl.to(".card", { y: 0, opacity: 1, duration: 0.6, ease: "power2.out", stagger: { // 错开入场 amount: 1, from: "start" } }); // 2. 为每个卡片添加悬停动画 const cards = document.querySelectorAll('.card'); cards.forEach(card => { let hoverTween = gsap.to(card, { scale: 1.05, boxShadow: "0 10px 30px rgba(0,0,0,0.2)", duration: 0.3, paused: true, // 创建即暂停,由事件触发 ease: "power2.inOut" }); card.addEventListener('mouseenter', () => hoverTween.play()); card.addEventListener('mouseleave', () => hoverTween.reverse()); // 使用reverse回到初始状态 }); // 3. 点击卡片全屏动画 let activeCardTween; cards.forEach(card => { card.addEventListener('click', function() { // 如果已有动画在进行,先复原 if (activeCardTween && activeCardTween.isActive()) { activeCardTween.reverse(); } // 创建新的全屏动画 activeCardTween = gsap.timeline() .to(this, { position: "fixed", zIndex: 1000, top: "50%", left: "50%", xPercent: -50, // 结合left:50%实现完美居中 yPercent: -50, width: "90vw", height: "90vh", borderRadius: "0", duration: 0.5, ease: "power2.inOut" }) .to(".card-detail", { // 假设卡片内有详情内容 opacity: 1, duration: 0.3 }, "-=0.2"); // 与上一个动画重叠0.2秒开始 }); });这个案例融合了时间轴、错开动画、控制方法(paused,reverse,isActive)、响应式单位(vw,vh,%)以及事件交互。它展示了如何将GSAP的各个基础模块组合起来,解决一个真实的交互需求。
最后,记住GSAP的强大在于其精确的控制和极高的性能。这份速查表是你探索这座宝藏的地图,但真正的熟练来自于动手实践。打开CodePen,把上面的例子敲一遍,改改参数,看看效果,很快你就能得心应手了。遇到复杂效果时,多想想如何用时间轴来编排,而不是堆砌delay。当你能够不假思索地写出流畅的动画代码时,你会发现,为网页注入生命力,是一件如此有成就感的事情。