GSAP 教程 - 高性能 JavaScript 动画库
一、项目概述
GSAP (GreenSock Animation Platform) 是一个功能强大的高性能 JavaScript 动画库,专为创建流畅、复杂的动画效果而设计。它提供了丰富的工具和 API,使开发者能够轻松创建各种动画效果,从简单的淡入淡出到复杂的时间线动画。
1.1 核心概念
- Tween:基本动画单元,用于定义元素从一个状态到另一个状态的过渡
- Timeline:时间线,用于组织和控制多个 Tween 的执行顺序和时间关系
- Easing:缓动函数,控制动画的速度变化
- Plugin:插件系统,扩展 GSAP 的功能
1.2 核心特点
- 高性能:经过高度优化,动画流畅度高
- 功能丰富:提供了全面的动画工具和 API
- 灵活性:支持各种动画场景和需求
- 跨浏览器兼容:在所有现代浏览器中表现一致
- 插件系统:通过插件扩展功能
二、安装与设置
2.1 安装方式
通过 npm 安装:
npm install gsap通过 CDN 引入:
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>2.2 基本引入
在 ES6 模块中:
import gsap from 'gsap';
// 引入插件
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { Draggable } from 'gsap/Draggable';
// 注册插件
gsap.registerPlugin(ScrollTrigger, Draggable);在浏览器中:
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/Draggable.min.js"></script>三、基础用法
3.1 创建基本 Tween 动画
简单的属性动画:
// 基本的淡入效果
gsap.to('.element', {
opacity: 1,
duration: 1,
ease: 'power2.out'
});
// 移动元素
gsap.to('.element', {
x: 100,
y: 50,
duration: 1.5,
ease: 'back.out(1.7)'
});
// 缩放元素
gsap.to('.element', {
scale: 1.2,
duration: 0.8,
ease: 'elastic.out(1, 0.5)'
});从某个状态开始动画:
// 从指定状态开始动画
gsap.from('.element', {
opacity: 0,
y: -50,
duration: 1,
ease: 'power2.out'
});
// 从当前状态动画到指定状态,再回到当前状态
gsap.fromTo('.element',
{ opacity: 0, scale: 0.8 }, // 起始状态
{ opacity: 1, scale: 1, duration: 1, ease: 'back.out' } // 结束状态
);3.2 使用 Timeline 组织动画
创建简单时间线:
// 创建时间线
const tl = gsap.timeline({
repeat: 2, // 重复次数
yoyo: true, // 往返动画
ease: 'power2.inOut'
});
// 添加动画到时间线
tl.to('.element1', { x: 100, duration: 1 })
.to('.element2', { y: 50, duration: 0.8 }, '-=0.5') // 与前一个动画重叠 0.5 秒
.to('.element3', { scale: 1.2, duration: 1 }, '+=0.3'); // 在前一个动画结束后延迟 0.3 秒开始标签和时间控制:
const tl = gsap.timeline();
// 添加标签
tl.add('start')
.to('.element1', { x: 100, duration: 1 })
.add('midpoint')
.to('.element2', { y: 50, duration: 0.8 })
.add('end');
// 使用标签控制动画
// 跳转到指定标签
tl.seek('midpoint');
// 从指定标签开始播放
tl.play('start');四、高级特性
4.1 ScrollTrigger 插件
基本滚动触发动画:
// 当元素进入视口时触发动画
gsap.registerPlugin(ScrollTrigger);
gsap.from('.section', {
scrollTrigger: {
trigger: '.section',
start: 'top 80%', // 当元素顶部到达视口80%位置时开始
end: 'bottom 20%', // 当元素底部到达视口20%位置时结束
toggleActions: 'play none none none' // 滚动时的行为:进入、离开、反向进入、反向离开
},
opacity: 0,
y: 50,
duration: 1,
ease: 'power2.out'
});滚动进度动画:
// 基于滚动进度的动画
gsap.registerPlugin(ScrollTrigger);
const tl = gsap.timeline({
scrollTrigger: {
trigger: '.scroll-section',
start: 'top top',
end: 'bottom bottom',
scrub: true // 滚动时 scrub 动画
}
});
tl.to('.element', { x: 300, duration: 1 })
.to('.element', { rotation: 360, duration: 1 })
.to('.element', { scale: 1.5, duration: 1 });4.2 Draggable 插件
基本拖拽功能:
// 基本拖拽
gsap.registerPlugin(Draggable);
Draggable.create('.draggable', {
type: 'x,y', // 拖拽方向
bounds: '.container', // 拖拽边界
inertia: true, // 惯性
onDragEnd: function() {
console.log('拖拽结束');
}
});拖拽排序:
// 拖拽排序
gsap.registerPlugin(Draggable);
Draggable.create('.item', {
type: 'x,y',
bounds: '.container',
dragResistance: 0.1,
onDragEnd: function() {
// 排序逻辑
sortItems();
}
});
function sortItems() {
// 实现排序逻辑
}4.3 自定义缓动函数
使用内置缓动:
// 内置缓动函数
gsap.to('.element', {
x: 100,
duration: 1,
ease: 'power1.inOut' // 内置缓动
});
// 弹性缓动
gsap.to('.element', {
x: 100,
duration: 1,
ease: 'elastic.out(1, 0.5)' // 弹性参数
});
// 反弹缓动
gsap.to('.element', {
x: 100,
duration: 1,
ease: 'back.out(1.7)' // 反弹强度
});创建自定义缓动:
// 创建自定义缓动
const customEase = gsap.parseEase('0.25, 0.1, 0.25, 1');
gsap.to('.element', {
x: 100,
duration: 1,
ease: customEase
});五、实际应用场景
5.1 页面滚动动画
视差滚动效果:
gsap.registerPlugin(ScrollTrigger);
// 视差背景
gsap.to('.parallax-bg', {
scrollTrigger: {
trigger: '.section',
scrub: true
},
y: (i, target) => {
return -(ScrollTrigger.maxScroll(window) * 0.5);
},
ease: 'none'
});
// 元素视差效果
gsap.to('.parallax-element', {
scrollTrigger: {
trigger: '.section',
scrub: true
},
y: 100,
ease: 'none'
});滚动触发的序列动画:
gsap.registerPlugin(ScrollTrigger);
const tl = gsap.timeline({
scrollTrigger: {
trigger: '.feature-section',
start: 'top 80%',
toggleActions: 'play none none none'
}
});
tl.from('.feature-title', { opacity: 0, y: 30, duration: 0.8 })
.from('.feature-item', {
opacity: 0,
y: 20,
duration: 0.6,
stagger: 0.2 // stagger 动画
}, '-=0.3');5.2 交互式动画
鼠标跟随效果:
// 鼠标跟随效果
window.addEventListener('mousemove', (e) => {
gsap.to('.cursor', {
x: e.clientX,
y: e.clientY,
duration: 0.1,
ease: 'power2.out'
});
});
// 鼠标悬停效果
document.querySelectorAll('.card').forEach(card => {
card.addEventListener('mouseenter', () => {
gsap.to(card, {
scale: 1.05,
boxShadow: '0 10px 30px rgba(0,0,0,0.1)',
duration: 0.3,
ease: 'back.out'
});
});
card.addEventListener('mouseleave', () => {
gsap.to(card, {
scale: 1,
boxShadow: '0 2px 10px rgba(0,0,0,0.05)',
duration: 0.3,
ease: 'power2.out'
});
});
});按钮点击动画:
// 按钮点击波纹效果
document.querySelectorAll('.btn').forEach(btn => {
btn.addEventListener('click', (e) => {
const rect = btn.getBoundingClientRect();
const size = Math.max(rect.width, rect.height);
const x = e.clientX - rect.left - size / 2;
const y = e.clientY - rect.top - size / 2;
// 创建波纹元素
const ripple = document.createElement('span');
ripple.classList.add('ripple');
ripple.style.width = ripple.style.height = size + 'px';
ripple.style.left = x + 'px';
ripple.style.top = y + 'px';
btn.appendChild(ripple);
// 动画
gsap.to(ripple, {
scale: 2,
opacity: 0,
duration: 0.6,
ease: 'power2.out',
onComplete: () => {
ripple.remove();
}
});
});
});5.3 数据可视化动画
数字计数动画:
// 数字计数动画
function animateCounter(element, start, end, duration) {
gsap.to({}, {
duration: duration,
start: start,
end: end,
ease: 'power2.out',
onUpdate: function() {
const value = Math.floor(this.targets()[0].start);
element.textContent = value.toLocaleString();
},
onComplete: function() {
element.textContent = end.toLocaleString();
}
});
}
// 使用示例
animateCounter(document.querySelector('.counter'), 0, 1000, 2);进度条动画:
// 进度条动画
function animateProgress(element, progress, duration) {
gsap.to(element, {
width: progress + '%',
duration: duration,
ease: 'power2.out'
});
}
// 使用示例
animateProgress(document.querySelector('.progress-bar'), 75, 1.5);六、性能优化建议
6.1 动画性能最佳实践
- 使用 transform 和 opacity:这些属性不会触发重排,性能更好
- 避免频繁 DOM 操作:使用 GSAP 的批量更新功能
- 合理使用 will-change:对于频繁动画的元素
- 使用 CSS 变量:结合 GSAP 动画 CSS 变量
- 优化时间线:合理组织动画顺序,避免重叠过多
6.2 代码优化示例
使用 CSS 变量:
// 定义 CSS 变量
:root {
--x: 0;
--y: 0;
--opacity: 1;
}
.element {
transform: translate(var(--x), var(--y));
opacity: var(--opacity);
}
// 动画 CSS 变量
gsap.to(':root', {
'--x': '100px',
'--y': '50px',
'--opacity': 0.5,
duration: 1
});使用 will-change:
.animated-element {
will-change: transform, opacity;
}批量动画:
// 批量创建动画
const elements = document.querySelectorAll('.items');
gsap.to(elements, {
x: 100,
duration: 1,
stagger: 0.1 // 错开动画
});七、常见问题与解决方案
7.1 动画不流畅
问题:动画在某些设备上不流畅
解决方案:
- 使用 transform 和 opacity 属性
- 避免在动画过程中修改布局属性
- 使用 will-change 提示浏览器
- 减少同时运行的动画数量
7.2 滚动触发动画不工作
问题:ScrollTrigger 插件的动画不触发
解决方案:
- 确保正确注册了 ScrollTrigger 插件
- 检查 trigger 元素是否存在
- 调整 start 和 end 配置
- 确保滚动容器正确设置
7.3 动画冲突
问题:多个动画同时作用于同一元素导致冲突
解决方案:
- 使用时间线统一管理动画
- 确保动画的时间不重叠
- 使用 GSAP 的 kill() 方法停止不需要的动画
- 考虑使用不同的元素进行动画
八、GSAP 与其他动画库的比较
8.1 GSAP vs CSS 动画
| 特性 | GSAP | CSS 动画 |
|---|---|---|
| 性能 | 极高,经过优化 | 好,但复杂动画性能下降 |
| 功能丰富度 | 非常丰富,支持复杂动画 | 基础,复杂动画需要更多代码 |
| 浏览器兼容性 | 优秀,支持所有现代浏览器 | 良好,但旧浏览器支持有限 |
| 控制能力 | 精确控制,支持暂停、恢复、跳转 | 基本控制,有限的交互能力 |
| 学习曲线 | 中等,需要学习 API | 低,使用 CSS 语法 |
8.2 GSAP vs Framer Motion
| 特性 | GSAP | Framer Motion |
|---|---|---|
| 性能 | 极高,专为性能优化 | 良好,针对 React 优化 |
| 适用范围 | 通用,支持所有前端框架 | 主要针对 React |
| 功能丰富度 | 非常丰富,包括 ScrollTrigger、Draggable 等 | 丰富,专注于 React 动画 |
| 集成难度 | 低,可与任何框架集成 | 低,专为 React 设计 |
| 社区支持 | 活跃,有大量资源 | 活跃,React 生态系统集成好 |
8.3 GSAP vs React Spring
| 特性 | GSAP | React Spring |
|---|---|---|
| 性能 | 极高,通用动画优化 | 良好,基于物理模型 |
| 动画模型 | 时间线和 tween 为主 | 基于物理模型 |
| 适用范围 | 通用,支持所有前端框架 | 主要针对 React |
| 功能丰富度 | 非常丰富,工具齐全 | 中等,专注于物理动画 |
| 学习曲线 | 中等,概念清晰 | 中等,物理概念需要理解 |
九、参考资源
9.1 官方资源
9.2 学习资源
9.3 工具与插件
十、总结
GSAP 是一个功能强大、性能优异的 JavaScript 动画库,为前端开发者提供了创建各种复杂动画效果的工具。它的核心优势在于:
- 高性能:经过高度优化,动画流畅度高
- 功能丰富:提供了全面的动画工具和 API
- 灵活性:支持各种动画场景和需求
- 跨浏览器兼容:在所有现代浏览器中表现一致
- 插件系统:通过插件扩展功能
无论是创建简单的 UI 交互效果,还是复杂的页面滚动动画,GSAP 都能轻松应对。它的 Timeline 系统让动画序列的管理变得简单直观,而各种插件(如 ScrollTrigger 和 Draggable)则进一步扩展了其能力范围。
通过本教程的学习,你应该已经掌握了 GSAP 的基本使用方法和高级特性,可以开始在项目中应用它来创建出色的动画效果了。随着实践经验的积累,你会发现 GSAP 能够帮助你实现几乎任何你能想象到的动画效果,为你的网站和应用增添生动的视觉体验。