JS 流行库(十一):GSAP
GSAP(GreenSock Animation Platform)是一个从 Flash 时代一直发展到现在的专业动画库,底层使用 JavaScript 实现,优点如下:
- 速度快
- 轻量级、模块化
- 无依赖
- 灵活控制
在 GSAP 2.X 的版本中,通过 TweenMax 类和 Tweenline 类实现动画效果,而在 GSAP 3.X 的版本中,将 TweenMax 和 Tweenline 包含到了 GSAP 类中,此处介绍 GSAP 3.X 版本的使用
基本使用
- 导入 GSAP 库
<script src="./js/gsap.js"></script>
- HTML
<style>
.box {
width: 100px;
height: 80px;
background-color: orangered;
}
</style>
<div class="box"></div>
- JavaScript
gsap.to(".box", {
x: 500,
duration: 3
});
上述示例的含义是将 box 在 3s 内从初始位置移动到 x 坐标为 500 的位置,此外,也可以使用 from 方法将 box 从某个位置移动到初始位置,示例如下:
gsap.from(".box", {
x: 500,
duration: 3
});
如果将元素从某个位置移动到另一个位置,那么可以使用 fromTo 方法,示例如下:
gsap.fromTo(".box", {
x: 500,
}, {
x: 300,
duration: 3
});
上述示例的含义是将元素从 x 坐标为 500 的位置在 3s 内匀速移动到 x 坐标为 300 的位置
如果想为多个元素添加动画,那么可以给元素添加相同的类名从而同时绑定动画,示例如下:
- HTML
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
}
.box:nth-of-type(2) {
background-color: orange;
}
.box:nth-of-type(3) {
background-color: green;
}
</style>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
- JavaScript
gsap.from(".box", {
x: 300,
duration: 2,
});
let oBoxs = document.querySelectorAll(".box");
oBoxs.forEach(function (box) {
box.addEventListener("click", function () {
gsap.to(".box", {
x: 500,
duration: 1,
ease: "elastic"
});
});
});
实际上,gsap 的 to、from 和 fromTo 方法可以以数组的形式传入待执行动画的元素,示例如下:
gsap.from(["div:nth-of-type(1)", "div:nth-of-type(2)", "div:nth-of-type(3)"], {
x: 300,
duration: 2,
});
如果以上述方式添加动画,那么所有被指定的元素将同时执行动画
此外,如果让所有元素在执行动画时错开执行,必须通过 stagger 属性来控制,示例如下:
gsap.from(".box", {
x: 300,
duration: 2,
stagger: 0.5
});
let oBoxs = document.querySelectorAll(".box");
oBoxs.forEach(function (box) {
box.addEventListener("click", function () {
gsap.to(".box", {
x: 500,
duration: 1,
ease: "elastic",
stagger: 0.5
});
});
});
上述示例中,stagger 属性表示在每一个元素执行动画后,下一个元素执行动画的间隔时间,此外,stagger 属性实际上还可以是一个实例,此处不再详细介绍
动画属性
通过 GSAP 给某个元素添加动画时,可以在传入的实例中设置动画属性,内容如下:
属性 | 类型 | 描述 |
---|---|---|
delay | Number | 延迟时间(单位:秒) |
duration | Number | 持续时间(单位:秒) |
ease | String | 动画效果(elastic 、strong.inOut 等) |
repeat | Number | 执行次数 |
repeatDelay | Number | 延迟时间(单位:秒) |
yoyo | Boolean | 往返动画 |
yoyoEase | String | 往返动画效果(类似于 ease 属性) |
startAt | Object | 初始位置 |
示例如下:
- HTML
<div class="box"></div>
- JavaScript
gsap.to(".box", {
x: 500,
duration: 5,
delay: 2,
ease: "elastic",
repeat: 3,
repeatDelay: 1,
yoyo: true,
yoyoEase: "strong.inOut"
});
必须注意的是,repeat 属性的含义是在原本执行次数的基础上的额外次数,所以上述示例在未设置 yoyo 属性时将执行 4 次,此外,如果未指定 yoyo 的动画效果,那么动画逆向执行时,动画也是颠倒执行的,另外,不论是正向执行还是逆向执行,均算一次执行,所以上述示例将执行 2 次往返动画
动画事件
通过 GSAP 给某个元素添加动画时,可以在传入的实例中监听动画事件,内容如下:
事件 | 描述 |
---|---|
onStart | 开始回调 |
onUpdate | 执行回调 |
onComplete | 结束回调 |
示例如下:
- HTML
<div class="box"></div>
- JavaScript
gsap.to(".box", {
x: 500,
delay: 2,
duration: 5,
onstart: function () {
console.log("Start"); // Start
},
onUpdate: function () {
console.log("Update"); // Update ...
},
onComplete: function () {
console.log("Complete"); // Complete
}
});
动画方法
实际上,在调用 gsap 的 to、from 和 fromTo 方法之后,将返回一个 Tween 实例,此实例有很多方法可以实时控制动画的执行,内容如下:
方法 | 描述 |
---|---|
pause | 停止 |
play | 开始 |
restart | 重置 |
paused | 暂停/继续 |
示例如下:
- HTML
<div class="box"></div>
<p>
<button id="pause-btn">Pause</button>
<button id="play-btn">Play</button>
<button id="restart-btn">Restart</button>
<button id="switch-btn">Switch</button>
</p>
- JavaScript
let myTween = gsap.to(".box", {
x: 500,
delay: 2,
duration: 5
});
let oPause = document.querySelector("#pause-btn");
oPause.onclick = function () {
myTween.pause();
}
let oPlay = document.querySelector("#play-btn");
oPlay.onclick = function () {
myTween.play();
}
let oRestart = document.querySelector("#restart-btn");
oRestart.onclick = function () {
myTween.restart();
}
let oSwitch = document.querySelector("#switch-btn");
oSwitch.onclick = function () {
myTween.paused(!myTween.paused());
}
如果动画在执行状态,那么 paused 方法将返回 false,如果动画在停止状态,那么 paused 方法返回 true,如果传入的参数为 true,那么 paused 方法将暂停动画,如果传入的参数为 false,那么 paused 方法将开启动画,所以上述示例的写法可以实现切换动画暂停与否的功能
动画序列
示例如下:
- HTML
<div class="box"></div>
- JavaScript
gsap.to(".box", {
x: 500,
duration: 3
});
gsap.to(".box", {
y: 300,
duration: 2,
delay: 3
});
gsap.to(".box", {
x: 800,
duration: 5,
delay: 5
});
上述示例中,为了实现各个执行动画,必须计算每个动画的延迟时间,GSAP 为了提高程序的可维护性,可以通过 gsap 调用 timeline 方法获得 Timeline 实例,此实例可以统一管理某些动画的执行,示例如下:
let tl = gsap.timeline();
tl.to(".box", {
x: 500,
duration: 3
});
tl.to(".box", {
y: 300,
duration: 2
});
tl.to(".box", {
x: 800,
duration: 5
});
上述示例中,通过 Timeline 实例的 to 方法为元素添加动画后,即使不指定延迟时间,所有动画将自动依次执行,此外,Timeline 存在实例方法 add,此方法可以以数组的形式添加 Tween 实例,示例如下:
tl.add([
gsap.to(".box", {
x: 500,
duration: 3
}),
gsap.to(".box", {
y: 300,
duration: 2
}),
gsap.to(".box", {
x: 800,
duration: 5
})
]);
上述示例中,元素的运动轨迹有所改变,原因在于,如果通过 add 实例方法添加若干动画,那么它们是同时执行的,所以通常使用 add 实例方法添加同时执行的一组动画,使用 to 实例方法添加一个动画,此外,实例方法 add 和 to 可以无限次的调用,所有动画都默认将以添加的序列依次执行,示例如下:
tl.add([
gsap.to(".box", {
x: 500,
duration: 3
}),
gsap.to(".box", {
y: 300,
duration: 2
}),
gsap.to(".box", {
x: 800,
duration: 5
})
]);
tl.to(".box", {
y: 400,
duration: 10
});
上述示例中,开始时,将同时执行 add 添加的 3 个动画,执行完毕后,再执行 to 添加的动画,此外,通过参数可以指定动画的次序,此处不再详细介绍