GSAP 动画库快速学习指南
📚 什么是GSAP?
GSAP (GreenSock Animation Platform) 是一个强大的JavaScript动画库,它让开发者能够轻松创建高性能、复杂的动画效果。无论是简单的元素动画,还是复杂的交互和视差效果,GSAP都能胜任。
为什么选择GSAP?
- 🚀 高性能:比CSS动画和其他JS动画库更流畅
- 🔄 跨浏览器兼容:解决各种浏览器兼容性问题
- 🛠️ 灵活强大:可以动画几乎任何属性(不限于CSS属性)
- 📊 精确控制:精确到0.01毫秒的时间轴控制
- 🧩 丰富的插件生态:ScrollTrigger、MotionPath等扩展功能
🌟 GSAP基础知识
1. 核心概念
GSAP有三个主要的动画方法:
// 从当前状态到指定状态(最常用)
gsap.to(".selector", {
x: 100, // 向右移动100px
duration: 1, // 动画持续1秒
ease: "power2.out" // 缓动函数
});
// 从指定状态到当前状态
gsap.from(".selector", {
opacity: 0, // 从透明开始
y: 50, // 从下方50px开始
duration: 1
});
// 从一个状态到另一个状态
gsap.fromTo(".selector",
{ opacity: 0, y: 50 }, // 起始状态
{ opacity: 1, y: 0, duration: 1 } // 结束状态
);
2. 基本属性
GSAP可以动画的常用属性:
| 属性 | 说明 | 示例 |
|---|---|---|
| x, y, z | 2D/3D位置 | x: 100 |
| rotation | 旋转(度) | rotation: 360 |
| scale | 缩放 | scale: 1.5 |
| opacity | 透明度 | opacity: 0 |
| backgroundColor | 背景色 | backgroundColor: "#ff0000" |
| width, height | 尺寸 | width: "100%" |
3. 控制动画
// 创建动画并保存引用
const animation = gsap.to(".box", {duration: 1, x: 100});
// 控制动画
animation.pause(); // 暂停
animation.play(); // 播放
animation.reverse(); // 反向播放
animation.restart(); // 重新开始
animation.progress(0.5); // 跳转到50%进度
🎯 GSAP常用功能
1. 时间轴(Timeline)
时间轴是GSAP的强大功能,可以精确排序多个动画:
// 创建时间轴
const tl = gsap.timeline({
defaults: { duration: 1 }, // 所有子动画的默认设置
paused: true, // 创建时不自动播放
repeat: 2 // 重复次数
});
// 添加动画到时间轴
tl.to(".box1", { x: 100 })
.to(".box2", { y: 50 }, "<") // "<"表示与前一个动画同时开始
.to(".box3", { scale: 1.5 }, "+=0.5") // 前一个动画结束后延迟0.5秒
.to(".box4", { opacity: 0 }, 2); // 在时间轴2秒处开始
2. ScrollTrigger插件
让动画与页面滚动关联:
// 注册插件
gsap.registerPlugin(ScrollTrigger);
// 基本用法
gsap.to(".element", {
x: 300,
scrollTrigger: {
trigger: ".element", // 触发元素
start: "top center", // 开始位置(元素顶部到达视口中心)
end: "bottom center", // 结束位置
scrub: true, // 动画跟随滚动进度
toggleActions: "play pause reverse reset", // 进入、离开等行为
markers: true // 调试标记(开发时使用)
}
});
3. 实用工具
// 设置初始状态
gsap.set(".element", { autoAlpha: 0, y: 20 });
// 批量处理多个元素
gsap.utils.toArray(".boxes").forEach((box, i) => {
gsap.to(box, { x: 100, delay: i * 0.1 });
});
// 随机值
gsap.to(".element", {
x: "random(-100, 100)", // 随机值
rotation: () => Math.random() * 360 // 使用函数返回随机值
});
🎭 GSAP视差效果实现
视差效果是指不同元素以不同的速度移动,从而产生深度感。以下是几种常见的视差效果实现方法:
1. 基础滚动视差
// 背景视差
gsap.to(".background", {
y: 200,
scrollTrigger: {
trigger: ".section",
start: "top top",
end: "bottom top",
scrub: true // 平滑跟随滚动
}
});
// 内容视差 (移动速度不同)
gsap.to(".content", {
y: -100, // 注意方向与背景相反
scrollTrigger: {
trigger: ".section",
start: "top top",
end: "bottom top",
scrub: true
}
});
2. 多层视差效果
关键在于不同层使用不同的移动速度:
// 远景层(移动慢)
gsap.to(".layer-bg", {
y: 50,
scrollTrigger: { trigger: ".section", scrub: 1 }
});
// 中景层(中等速度)
gsap.to(".layer-mid", {
y: 100,
scrollTrigger: { trigger: ".section", scrub: 1 }
});
// 前景层(移动快)
gsap.to(".layer-fg", {
y: 150,
scrollTrigger: { trigger: ".section", scrub: 1 }
});
3. 鼠标跟随视差
使用鼠标位置创建视差效果:
document.addEventListener("mousemove", (e) => {
// 计算鼠标位置相对于窗口中心的偏移
const centerX = window.innerWidth / 2;
const centerY = window.innerHeight / 2;
const offsetX = (e.clientX - centerX) / centerX;
const offsetY = (e.clientY - centerY) / centerY;
// 不同元素应用不同的移动速度
gsap.to(".layer1", {
x: offsetX * 20, // 慢速移动
y: offsetY * 20,
duration: 1
});
gsap.to(".layer2", {
x: offsetX * 40, // 中速移动
y: offsetY * 40,
duration: 1
});
gsap.to(".layer3", {
x: offsetX * 60, // 快速移动
y: offsetY * 60,
duration: 1
});
});
4. 视差卡片效果
当滚动到卡片时,可以使用不同的动画参数:
gsap.utils.toArray(".card").forEach((card, i) => {
// 每个卡片有不同的动画参数
gsap.to(card, {
y: i * 40, // 不同的移动距离
rotation: i % 2 ? 5 : -5, // 交替旋转方向
scrollTrigger: {
trigger: card,
start: "top bottom",
end: "bottom top",
scrub: 1
}
});
});
💼 实际案例解析
示例1:滚动触发的元素淡入效果
// 元素从底部淡入
gsap.utils.toArray(".fade-in").forEach(element => {
gsap.from(element, {
opacity: 0,
y: 50,
duration: 1,
scrollTrigger: {
trigger: element,
start: "top 80%", // 当元素顶部达到视口80%位置时
toggleActions: "play none none none"
}
});
});
示例2:视差图片画廊
const images = gsap.utils.toArray(".gallery img");
images.forEach((image, i) => {
// 创建交错的动画效果
gsap.to(image, {
y: (i % 2 === 0) ? -100 : 100, // 交替上下移动
scrollTrigger: {
trigger: ".gallery",
start: "top bottom",
end: "bottom top",
scrub: true
}
});
});
示例3:文字分段动画
// 将文本拆分为字符
const splitText = new SplitText(".heading", {type: "chars"});
const chars = splitText.chars;
// 创建交错动画
gsap.from(chars, {
opacity: 0,
y: 50,
stagger: 0.05, // 每个字符间隔0.05秒
duration: 0.8,
ease: "back.out"
});
一个比较完整示例
可以直接拷贝到html文件中双击运行
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GSAP 视差效果示例</title>
<!-- 引入 GSAP 核心库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
<!-- 引入 ScrollTrigger 插件,用于滚动触发动画 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
overflow-x: hidden;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.container {
width: 100%;
min-height: 100vh;
}
/* 示例1:基础视差区域 */
.parallax-section {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.parallax-bg {
position: absolute;
width: 100%;
height: 120%;
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
z-index: 0;
}
.parallax-content {
position: relative;
z-index: 1;
text-align: center;
color: white;
}
.parallax-content h1 {
font-size: 4rem;
margin-bottom: 20px;
}
/* 示例2:多层视差卡片 */
.cards-section {
padding: 100px 20px;
min-height: 100vh;
}
.cards-section1 {
padding: 100px 20px;
min-height: 100vh;
}
.card {
width: 300px;
height: 400px;
margin: 50px auto;
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
font-weight: bold;
color: #667eea;
}
/* 示例3:图片视差层 */
.image-parallax-section {
height: 100vh;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.parallax-layer {
position: absolute;
width: 200px;
height: 200px;
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
font-size: 3rem;
}
.layer-1 { background: #ff6b6b; top: 20%; left: 10%; }
.layer-2 { background: #4ecdc4; top: 50%; left: 60%; }
.layer-3 { background: #45b7d1; top: 70%; left: 30%; }
/* 示例4:文字视差 */
.text-parallax-section {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #1a1a2e;
position: relative;
overflow: hidden;
}
.text-parallax-wrapper {
text-align: center;
}
.parallax-text {
font-size: 5rem;
font-weight: bold;
color: white;
margin: 20px 0;
opacity: 0;
}
/* 示例5:鼠标跟随视差 */
.mouse-parallax-section {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
position: relative;
overflow: hidden;
}
.mouse-parallax-item {
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
background: rgba(255,255,255,0.3);
}
.mouse-parallax-item:nth-child(1) { width: 150px; height: 150px; }
.mouse-parallax-item:nth-child(2) { width: 100px; height: 100px; }
.mouse-parallax-item:nth-child(3) { width: 80px; height: 80px; }
.section-title {
position: absolute;
top: 50px;
left: 50%;
transform: translateX(-50%);
color: white;
font-size: 2rem;
z-index: 10;
}
</style>
</head>
<body>
<div class="container">
<!-- 示例1:基础背景视差效果 -->
<section class="parallax-section">
<h1 style="color: white;z-index: 111;">GSAP 视差效果</h1>
<div class="parallax-bg" id="parallax-bg"></div>
<div class="parallax-content" id="parallax-content">
<h1>GSAP 视差效果</h1>
<p>向下滚动查看更多示例</p>
</div>
</section>
<!-- 示例2:卡片视差效果 -->
<section class="cards-section">
<div class="card card-1">卡片 1</div>
<div class="card card-2">卡片 2</div>
<div class="card card-3">卡片 3</div>
</section>
<!-- 示例2:卡片视差效果 -->
<section class="cards-section1">
<div class="card card-1">卡片 1</div>
<div class="card card-2">卡片 2</div>
<div class="card card-3">卡片 3</div>
</section>
<!-- 示例3:多层图片视差 -->
<section class="image-parallax-section">
<h2 class="section-title">多层视差效果</h2>
<div class="parallax-layer layer-1">🌟</div>
<div class="parallax-layer layer-2">🚀</div>
<div class="parallax-layer layer-3">🎨</div>
</section>
<!-- 示例4:文字交错视差 -->
<section class="text-parallax-section">
<div class="text-parallax-wrapper">
<div class="parallax-text text-1">欢迎</div>
<div class="parallax-text text-2">学习</div>
<div class="parallax-text text-3">GSAP</div>
</div>
</section>
<!-- 示例5:鼠标跟随视差 -->
<section class="mouse-parallax-section" id="mouse-section">
<h2 class="section-title">移动鼠标查看效果</h2>
<div class="mouse-parallax-item" data-speed="0.5"></div>
<div class="mouse-parallax-item" data-speed="0.3"></div>
<div class="mouse-parallax-item" data-speed="0.2"></div>
</section>
</div>
<script>
// 注册 ScrollTrigger 插件
// ============================================================
// 示例1:基础背景视差效果
// 背景移动速度比内容慢,产生视差效果
// ============================================================
gsap.to("#parallax-bg", {
// y 轴向下移动 200px
y: 200,
// 滚动触发器配置
scrollTrigger: {
trigger: ".parallax-section", // 触发元素
start: "top top", // 动画开始位置(元素顶部到达视口顶部时)
end: "bottom top", // 动画结束位置(元素底部到达视口顶部时)
scrub: true, // 平滑跟随滚动(true 表示直接绑定滚动进度)
// markers: true // 开启此项可显示调试标记
}
});
// 内容淡出效果
gsap.to("#parallax-content", {
opacity: 0,
y: 100,
scrollTrigger: {
trigger: ".parallax-section",
start: "top top",
end: "bottom top",
scrub: true // 平滑跟随滚动(true 表示直接绑定滚动进度)
}
});
// ============================================================
// 示例2:卡片交错视差动画
// 每个卡片有不同的移动速度和旋转效果
// ============================================================
gsap.utils.toArray(".cards-section .card").forEach((card, index) => {
// 根据索引设置不同的视差速度
const speed = (index + 1) * 50;
gsap.to(card, {
y: speed, // 向下移动
rotation: 10, // 旋转10度
scrollTrigger: {
trigger: card,
start: "top bottom", // 卡片顶部进入视口底部时开始
end: "bottom top", // 卡片底部离开视口顶部时结束
scrub: 1, // 平滑度为1(数字越大越平滑)
}
});
// 入场动画:从左侧淡入
gsap.from(card, {
x: -200, // 从左侧200px外
opacity: 0, // 透明度从0开始
duration: 1, // 动画持续1秒
scrollTrigger: {
trigger: card,
start: "top 80%", // 卡片顶部到达视口80%位置时触发
toggleActions: "play none none reverse" // 进入播放,离开反转
}
});
});
gsap.utils.toArray(".cards-section1 .card").forEach((card, index) => {
// 根据索引设置不同的视差速度
const speed = (index + 1) * 50;
gsap.to(card, {
y: speed, // 向下移动
rotation: -10, // 旋转10度
scrollTrigger: {
trigger: card,
start: "top bottom", // 卡片顶部进入视口底部时开始
end: "bottom top", // 卡片底部离开视口顶部时结束
scrub: 1, // 平滑度为1(数字越大越平滑)
}
});
// 入场动画:从左侧淡入
gsap.from(card, {
x: 200, // 从左侧200px外
opacity: 0, // 透明度从0开始
duration: 1, // 动画持续1秒
scrollTrigger: {
trigger: card,
start: "top 80%", // 卡片顶部到达视口80%位置时触发
toggleActions: "play none none reverse" // 进入播放,离开反转
}
});
});
// ============================================================
// 示例3:多层视差效果
// 不同层有不同的移动速度,创造深度感
// ============================================================
gsap.to(".layer-1", {
y: -150, // 最快的层
x: 100,
scrollTrigger: {
trigger: ".image-parallax-section",
start: "top bottom",
end: "bottom top",
scrub: 1
}
});
gsap.to(".layer-2", {
y: -100, // 中等速度
x: -80,
scrollTrigger: {
trigger: ".image-parallax-section",
start: "top bottom",
end: "bottom top",
scrub: 1
}
});
gsap.to(".layer-3", {
y: -50, // 最慢的层
x: 60,
scrollTrigger: {
trigger: ".image-parallax-section",
start: "top bottom",
end: "bottom top",
scrub: 1
}
});
// ============================================================
// 示例4:文字交错视差效果
// 文字按顺序出现,每个有不同的延迟和移动距离
// ============================================================
const textTimeline = gsap.timeline({
scrollTrigger: {
trigger: ".text-parallax-section",
start: "top 60%",
end: "bottom 60%",
scrub: 1
}
});
// 添加交错动画到时间轴
textTimeline
.to(".text-1", { opacity: 1, y: 0, duration: 0.5 })
.to(".text-2", { opacity: 1, y: 0, duration: 0.5 }, "-=0.2") // 提前0.2秒开始
.to(".text-3", { opacity: 1, y: 0, duration: 0.5 }, "-=0.2");
// 设置初始位置
gsap.set(".parallax-text", { y: 100 });
// ============================================================
// 示例5:鼠标跟随视差效果
// 鼠标移动时,元素根据speed属性以不同速度跟随
// ============================================================
const mouseSection = document.getElementById("mouse-section");
const mouseItems = document.querySelectorAll(".mouse-parallax-item");
mouseSection.addEventListener("mousemove", (e) => {
// 获取鼠标相对于视口的位置
const mouseX = e.clientX;
const mouseY = e.clientY;
// 获取视口中心点
const centerX = window.innerWidth / 2;
const centerY = window.innerHeight / 2;
// 计算鼠标偏移量
const offsetX = (mouseX - centerX) / centerX;
const offsetY = (mouseY - centerY) / centerY;
mouseItems.forEach((item) => {
// 获取每个元素的速度属性
const speed = parseFloat(item.getAttribute("data-speed"));
// 根据速度计算移动距离
const moveX = offsetX * 100 * speed;
const moveY = offsetY * 100 * speed;
// 使用 GSAP 动画移动元素
gsap.to(item, {
x: moveX,
y: moveY,
duration: 1.5, // 动画持续时间
ease: "power2.out" // 缓动函数
});
});
});
// 设置鼠标跟随元素的初始位置(随机分布)
mouseItems.forEach((item, index) => {
gsap.set(item, {
x: Math.random() * window.innerWidth - 100,
y: Math.random() * window.innerHeight - 100
});
});
// ============================================================
// 额外技巧:页面加载时的入场动画
// ============================================================
window.addEventListener("load", () => {
gsap.from("#parallax-content h1", {
scale: 0, // 从0开始缩放
rotation: 360, // 旋转360度
duration: 1.5, // 持续1.5秒
ease: "back.out(1.7)" // 回弹缓动效果, 控制回弹的强度, 数值越大, 回弹越强烈
});
gsap.from("#parallax-content p", {
opacity: 0,
y: 50,
duration: 1,
delay: 0.5, // 延迟0.5秒开始
ease: "power2.out" // 缓动函数, 控制动画的速度变化, 数值越大, 速度越快
});
});
</script>
</body>
</html>
🧠 GSAP学习策略
1. 学习路线
- 基础动画 - 掌握to, from, fromTo方法
- 时间轴 - 学习如何编排多个动画
- ScrollTrigger - 掌握滚动触发动画
- 高级功能 - 探索MotionPath, SplitText等插件
- 性能优化 - 学习如何创建高性能动画
2. 实践建议
- 🔍 拆解喜欢的网站动画 - 查看优秀网站的源代码
- 🧪 从简单开始 - 先实现简单动画,逐步添加复杂度
- 📝 保持代码组织 - 使用时间轴组织复杂动画
- 🐞 使用调试工具 - ScrollTrigger的markers功能
- 🔄 频繁迭代 - 不断尝试不同参数观察效果
3. 常见陷阱
- 🚫 过度动画 - 动画太多会分散注意力
- ⚠️ 性能问题 - 注意移动设备上的性能
- 🔍 兼容性 - 测试不同浏览器和设备
- 🕰️ 时机控制 - 注意动画的开始和结束时机