GSAP (GreenSock Animation Platform),构建适用于所有主流浏览器的高性能动画。可应用于JavaScript相关的任何东西:动画 CSS、SVG、画布、React、Vue、WebGL、颜色、字符串、运动路径、通用对象......
1. Gsap入门
Gsap官方入门教程: greensock.com/get-started…
1.1 Gsap下载和引用
npm install gsap
import gsap from 'gsap'
// 或者 import { gsap } from 'gsap'
1.2 Gsap实现一些简单的动画
1-2-1 gsap.to()
gsap.to(选择器,状态对象)
是指从原有状态 变化成参数里的状态对象
// html元素创建动画,将 '.box' 类的元素设置3秒时间水平移动 300px 的动画
gsap.to(".box",{
duration: 3,
x: 300
})
gsap.to()
- 最常见的补间类型。当前元素或者变量的状态,过渡到目标状态的补间动画。
所谓的补间动画,就是2个关键帧(即2种物体的状态)有了,框架自带计算出中间某个时刻的状态,从而填补2个状态间,动画的空白时刻,从而实现完整动画。
gsap.to
有2个参数,第一个是目标元素或者变量。
- 如果传入的是.box之类的css字符串选择器,GSAP 在后台使用
document.querySelectorAll()
选中页面的匹配的元素。 - 当第一个目标是对象时,GSAP就会对其属性值进行修改来实现补间动画。
1-2-2 gsap.from()
gsap.from(选择器,状态对象) 是指从参数里的状态对象表现的状态 回归成现有的状态
gsap.from(".circle", { x: -40, fill: 'blue', });
1-2-3 gsap.fromTo()
gsap.fromTo(选择器,状态对象A,状态对象B)是指从状态B,回归到状态A
gsap.fromTo( ".circle",{ x: -40, fill: 'blue', }, { x: 40, fill: 'green' });
1.3 gsap.to()的两个参数
1-3-1 第一个参数——CSS选择器或者Object对象
可以是一个 CSS选择器、Element 也可以是一个 Object 对象
const obj = { props: 3 }
gsap.to(obj, {
props: 100,
duration: 3,
onUpdate: function (a, b, c) {
console.log(obj.props)
}
})
1-3-2 第二个参数——目标状态对象
第二个参数是个对象,接受动画的目标状态,为了区分类型和后续方便理解,它的属性包含三种类型,动画状态、运动方式、回调函数
1-3-2-1 动画状态的控制属性
参数 | 释义 |
---|---|
delay : 2 | 延时播放,单位s |
duration : 3 | 动画持续时间,单位s |
repeat : 3 | 动画重复播放的次数,-1为一直重复 |
repeatDelay: 3 | 重复播放间隔时间,单位s |
yoyo : false | 如果true,每隔一个重复,东环将沿相反方向运行 |
ease : "bounce" | 控制动画期间的变化率 |
paused: true | true 暂停播放动画 |
stagger : { grid: [7,15], from: "end", axis: "x", ease: "power3.inOut", amount: 1.5 } | 交错动画 |
1-3-2-2 运动方式——CSS属性
参数 | 相对应的CSS |
---|---|
x: 100 | transform: translateX(100px) |
y: 100 | transform: translateY(100px) |
rotation: 360 | transform: rotate(360deg) |
rotationX: 360 | transform: rotateX(360deg) |
rotationY: 360 | transform: rotateY(360deg) |
skewX: 45 | transform: skewX(45deg) |
skewY: 45 | transform: skewY(45deg) |
scale: 2 | transform: scale(2, 2) |
scaleX: 2 | transform: scaleX(2) |
scaleY: 2 | transform: scaleY(2) |
xPercent: -50 | transform: translateX(-50%) |
yPercent: -50 | transform: translateY(-50%) |
width: 100 | width: 100px |
height: '10vh' | height: 10vh |
1-3-2-3 动画的回调函数
事件 | 释义 |
---|---|
onStart | 动画开始播放时触发 |
onComplete | 所有动画播放完毕后调用的函数(如果有repeat,则等所有的循环结束后执行) |
onRepeat | 如果有repeat一组动画播放完的回调函数 |
onUpdate | 动画运动过程中的回调函数 |
onReverseComplete | 触发reverse后回到起点时触发 |
1-3-2-4 ease属性——动画的速度变化
在引擎内部,“ease”是一种数学计算,用于控制补间期间的变化率。框架会为您做所有的数学计算!只需选择最适合的动画的效果即可。
对于大多数效果,分为三种类型in、out、inOut。这些控制了动画过程中的动量。
像这样的 设置ease:"power1.out"
是 UI 过渡的最佳选择;它们开始速度很快,在接近结束时变慢。
ease: "power1.in"
// start slow and end faster, like a heavy object falling
ease: "power1.out"
// start fast and end slower, like a rolling ball slowly coming to a stop
ease: "power1.inOut"
// start slow and end slow, like a car accelerating and decelerating
地址:GreenSock | Docs | Eases
1-3-2-5 Staggers 动画添加交错效果
在每个动画的开始之间添加一些交错效果:
stagger
设置0.2,即为将.box选中的多个元素设置为每隔0.2秒开始运动1个元素的效果。
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js"></script>
<link
rel="stylesheet"
href="https://codepen.io/GreenSock/pen/gOWxmWG.css"
/>
<style>
@import url('https://fonts.googleapis.com/css2?family=Signika+Negative:wght@400;600&display=swap');
body {
display: flex;
align-items: center;
justify-content: space-around;
min-height: 100vh;
font-family: 'Signika Negative', sans-serif;
}
h3 {
position: fixed;
top: 0;
width: 100%;
text-align: center;
}
.box {
cursor: pointer;
}
</style>
</head>
<body>
<div class="box green"></div>
<div class="box purple"></div>
<div class="box orange"></div>
<div class="box purple"></div>
<div class="box green"></div>
<h3>Click a box to transition out</h3>
<script>
gsap.from('.box', {
duration: 2,
scale: 0.5,
opacity: 0,
delay: 0.5,
stagger: 0.2,
ease: 'elastic',
force3D: true
})
document.querySelectorAll('.box').forEach(function (box) {
box.addEventListener('click', function () {
gsap.to('.box', {
duration: 0.5,
opacity: 0,
y: -100,
stagger: 0.1,
ease: 'back.in'
})
})
})
</script>
</body>
</html>
1-3-2-6 时间线-Timelines
时间线用于创建一组按照顺序播放的动画。当您将补间添加到时间线时,默认情况下,它们会按照添加的顺序一个接一个地播放。
// 创建时间线动画
let tl = gsap.timeline()
// 现在用时间线tl代替上边的gsap来设置动画即可。
tl.to(".green", { x: 600, duration: 2 });
tl.to(".purple", { x: 600, duration: 1 });
tl.to(".orange", { x: 600, duration: 1 })
1.4 gsap.to()的返回值——控制动画的进行
gasp.to 等执行后会返回一个 tween 实例。它有一些 api 可以控制动画的进行,比如:
const tween = gsap.to('body', {
x: 300,
duration: 3
})
console.log(tween.duration()) // 相当于Getter 获取当前动画总共需要执行3秒
tween.duration(1)
console.log('返回值tween实例', tween)
console.log('原型', tween.__proto__.__proto__)
上述代码,原先动画的执行时间是 duration: 3
需要3秒才能完成动画的播放
但通过设置了tween.duration(1)
后,动画总时长只执行了1秒
api | 释义 |
---|---|
time | 从哪个时刻开始执行动画,单位是秒 |
progress | 从哪个进度开始,参数是 0 ~ 1 |
duration | 更改整体动画时间,参数是期望的动画的总时间 |
delay | 延时几秒后执行动画,参数是秒 |
timeScale | 动画播放速度,数值越大,播放速度越快修改后的播放时间 = 原播放总时长 / timeScale |
1.4.1 控制动画播放
通过返回的实例控制播放
const tween = gsap.to('.green', {
duration: 4,
x: 750,
rotation: 360
})
setTimeout(() => {
tween.pause()
}, 2000)
上述动画原本会持续4秒,2秒过后,触发了 tween.pause()
动画暂停
api | 释义 |
---|---|
play | 播放 |
pause | 暂停 |
resume | 继续播放,只能继pause之后播放 |
reverse | 回退到起始点 |
restart | 从头开始播放 |
kill | 直接暂停并销毁实例,后续无法重新播放 |
2 Threejs场景中使用Gsap动画
2.1 设置立方体旋转
gsap.to(
cube.rotation,
{
x: 2 * Math.PI,
duration: 5,
repeat: -1,
ease: "power1.inOut"
}
);
2.2 设置立方体来回往返运动
// 设置动画
var animate1 = gsap.to(cube.position, {
x: 3,
duration: 3,
ease: 'power1.inOut',
// 设置重复的次数,无限次循环-1
repeat: -1,
// 往返运动
yoyo: true,
// delay,延迟2秒运动
delay: 2,
// 当动画完成时,执行回调函数
onComplete: () => {
console.log('动画完成')
},
onRepeat: () => {
console.log('动画重复一次')
},
//当动画开始时,执行回调函数
onStart: () => {
console.log('动画开始')
}
})
2.3 控制立方体动画暂停和恢复动画
让双击画面,控制立方体动画暂停和恢复动画。
- 前面创建的animate1这个动画实例,有isActive方法,可以用来获取当前动画是暂停还是播放状态,
- 播放状态时isActive方法返回为true,暂停时为false,根据这个状态来调用pause方法来暂停动画和恢复动画。
window.addEventListener("dblclick", () => {
// console.log(animate1);
if (animate1.isActive()) {
// 暂停
animate1.pause();
} else {
// 恢复
animate1.resume();
}
});
2.4 暂停单个动画——Gsap效果实例
import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import gsap from 'gsap'
// console.log(gsap)
// 目标:Three使用Gsap动画
// 1、创建场景
const scene = new THREE.Scene()
// 2、创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
)
// 设置相机位置
camera.position.set(0, 0, 10)
scene.add(camera)
// 添加物体
// 创建几何体
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1)
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 })
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
// 将几何体添加到场景中
scene.add(cube)
// console.log(cube)
// 初始化渲染器
const renderer = new THREE.WebGLRenderer()
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight)
// console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement)
// 添加坐标轴辅助器
const axesHelper = new THREE.AxesHelper(3)
scene.add(axesHelper)
// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
var animate1 = gsap.to(cube.position, {
x: 3,
duration: 3,
ease: 'power1.inOut',
// 设置重复的次数,无限次循环-1
repeat: -1,
// 往返运动
yoyo: true,
// delay,延迟2秒运动
delay: 2,
// 当动画完成时,执行回调函数
onComplete: () => {
console.log('动画完成')
},
onRepeat: () => {
console.log('动画重复一次')
},
//当动画开始时,执行回调函数
onStart: () => {
console.log('动画开始')
}
})
gsap.to(cube.rotation, {
x: 2 * Math.PI,
duration: 3,
repeat: -1,
ease: 'power1.inOut'
})
window.addEventListener('dblclick', () => {
// console.log(animate1);
if (animate1.isActive()) {
// 暂停平移动画animate1
// 旋转动画不受影响
animate1.pause()
} else {
// 恢复动画animate1
animate1.resume()
}
})
function render() {
renderer.render(scene, camera)
requestAnimationFrame(render)
}
render()