以下内容是个整体功能的描述,不会对所有 api 进行说明讲解,主要是关键性内容描述。
# 前言
作为一个前端开发,不可避免地需要开发动画。如果自己临时写一个动画,还是比较容易出问题的,今天介绍一个很好用的动画库,功能十分强悍 ———— GSAP。
# 效果
说再多,也不如直接来效果来的直观。
如果能科学上网可以查看以下官网链接:
- GSAP 动画:greensock.com/showcase/
- GSAP ScrollTrigger(gsap 的插件)动画:greensock.com/st-demos/
# GSAP
# 安装 && 基础 api
# 安装
pnpm install gsap
(其他方式也行,注意:在 vue、react 等框架下使用,应在 dom 渲染后调用)
# to:
- 代码:
gsap.to(目标dom, { x: 300, y: 100, duration: 1, ease: 'back' })
- 效果说明:目标 dom,translate (300px,100px),持续过程 1s,过渡动画:back(后面讲解)
- 效果:
# from:
- 代码:
gsap.from(目标dom, { x: 300, duration: 1, delay: 1 })
- 效果说明:目标 dom,初始化 translateX (300px),然后回到原本代码的位置,持续过程 1s,延长 1s 执行
- 效果:
# fromTo:
- 代码:
gsap.fromTo(目标dom, { x: 300, y: 100 }, { x: 100, y: 50 })
- 效果说明:目标 dom,初始化 translate (300px, 100px),去往 translateX (100px, 50px),持续过程:默认时间
- 效果:
# 常用参数说明
例如: gsap.to(to.value, { x: 300, y: 100 })
,参数是:x、y
# 参数列表
- keyframes:类似 css 的 keyframes,执行多段动画,例如:
gsap.to(目标dom, { keyframes: [{x: 100}, {y: 100}] })
- esae:缓冲动画函数。
- x、y:移动到 x、y 的位置,对应 api:translate
- duration: 动画持续时间,单位: s
- delay:动画延迟执行,单位:s
- repeat:重复执行动画,单位:次,无限次数则:-1
- yoyo:是否原路返回执行,配合 repeat 使用。例如:yoyo: false,执行:1-2-3-1-2-3-1-2-3;则,yoyo:true,执行效果:1-2-3-3-2-1-1-2-3
- repeatDelay: repeat 延迟执行,单位:s
- 其他:top、left、borderSize、borderRaduis、width、height 等 css 属性
# Hooks
- onComplete:动画执行完成回调;回调函数的参数:onCompleteParams: any []
- onRepeat:动画重复执行回调;回调函数的参数:onRepeatParams: any []
- onStart:动画重复执行回调;回调函数的参数:onStartParams: any []
例如:
gsap.to(目标dom, { | |
width: 'auto', | |
repeat: 3, | |
repeatDelay: 0.5, | |
yoyo: true, | |
esas: 'back', | |
onRepeatParams: [1, '2', 3], | |
onRepeat() { | |
console.log('重复执行的回调') | |
console.log('回调的参数:', arguments) | |
}, | |
onComplete() { | |
console.log('动画执行完成') | |
}, | |
onStart() { | |
console.log('动画从起始位置开始执行,即repeat会重复触发') | |
} | |
}) |
# 关键 api:Timeline
# 先看效果
1. 代码:
const t1 = gsap.timeline() | |
t1.to(目标dom, { x: 300, duration: 0.5 }) | |
.to(目标dom, { y: 100, duration: 1 }) | |
.to(目标dom, { x: 0, y: 0, duration: 1 }) |
代码说明:实例化一个 timeline,对一个或者多个目标 dom 进行时间轴的动画效果。时间轴时间长度为:实例内 duration
的总长度,根据链式调用的顺序和时间,进行依次调用,上一个 dom 动画完成再到下一个 dom 动画(可以是同一个 dom,也可以是不同的 dom)。
2. 效果:
# Timeline 详解
一个复杂的动画由多个补间动画组成的,而 timeline 的作用就是整体上串联所有的补间动画
# 多 dom 例子
//timeline 重复两次,每次重复延迟 2s | |
const tl = gsap.timeLine({repeat:2,repeatDelay:2}) | |
//box1 先向右移动 100 像素,耗时 1 秒,接着 box2 向下平移 100 像素,耗时 1 秒 | |
tl.to('.tl_1',{x: 100, duration: 1}) | |
tl.to('.tl_2',{y: 100,duration: 1}) |
# 时间轴定义
# 默认序列
# 相对序列
# 绝对序列
# label 序列
# 常用参数
- repeat: 时间轴动画重复次数,类型 number
- repeatDelay: 重复动画间隔时间(以秒为单位),类型 number
- yoyo:重复动画交替方式,类型 boolean(同上文 yoyo)
- delay:时间轴开始之前的延迟(以秒为单位),类型 number
- reversed:时间轴动画是否倒放,类型 boolean
- onComplete: 时间轴动画完成回调,类型 (...args: any []) => void | null
- onRepeat:时间轴动画重复执行回调,类型 (...args: any []) => void | null
- onStart: 时间轴动画开始执行回调,类型 (...args: any []) => void | null
- onUpdate:时间轴动画运行时回调,类型 (...args: any []) => void | null
- autoRemoveChildren:动画完成是否杀死补间动画,好处减少内存占用,类型 boolean
# 常用函数(以下 tl 是:const t1 = gsap.timeline ()
实例方法可能会破坏,原本参数的预期的动画和参数的设定
与上述例子相同,onComplete 勾子,添加 reverse 方法,会发现重复执行参数不生效:
const tl = gsap.timeline({ repeat: 2, repeatDelay: 2 }) | |
//box1 先向右移动 100 像素,耗费 1 秒,接着 box2 向下平移 100 像素,耗费 1 秒 | |
tl.to('.tl_1', { x: 100, duration: 1 }) | |
tl.to('.tl_2', { | |
y: 100, | |
duration: 1, | |
onComplete: () => { | |
tl.reverse() | |
} | |
}) |
- tl.pause (): 暂停动画
- tl.reverse (): 反向播放动画
- tl.add (): 添加补间动画(对比上面和下面的 timeline 例子)
- tl.addLabel (): 在时间线上添加标签,便于标记重要位置 / 时间
const tl = gsap.timeLine() | |
tl.add(gsap.to('.box',{x:100,duration:2})) | |
// 在.box 动画运行 2 秒后,再等 1 秒做个记录,也就是 firstStep 是 3 秒的标记 | |
tl.addLabel('timeFlag','+=1') | |
// 这时.box1 执行的时间是: .box 执行时间 + 标记加上的时间 = 3s 开始 | |
tl.add(gsap.to('.box1',{x:100,duration:1}, 'timeFlag')) |
- tl.seek (): 跳到指定的时间
const tl = gsap.timeLine() | |
tl.seek(1) // 跳到 1 秒初 | |
tl.seek('+=1') // 相对时间,当时时间 + 1 | |
tl.seek('label') // 跳到指定标签处 (应先添加 label) |
- tl.progress (): 进度跳转在 0~1 之间
- tl.kill (): 杀死动画
- tl.to
- tl.from
- ......
# GSAP ScrollTrigger
ScrollTrigger 是 GSAP 的插件,它监听页面滚动,然后执行对应的 gsap。
简单点理解:ScrollTrigger 就是,让页面滚动条等价于 timeline 的时间轴,滚动页面就是 timeline 时间轴前进,回滚则是时间轴回退。
ScroolTrigger 有多种方式运行,以下我们主要以 timeline + scrollTrigger 作为例子。
# 示例代码 && 解释
# 代码
const tl = this.$gsap.timeline({ | |
scrollTrigger: { | |
trigger: 相对dom, | |
start: 'top 500px', | |
end: 'bottom 500px', | |
scrub: 0.1, | |
markers: true | |
} | |
}) | |
tl.to(动画dom, { x: 100, opacity: 0 }) |
# 代码解释
我们可以看到 timeline () 里面多了 scrollTrigger
的参数集,以下对上面代码的参数集进行解释:
trigger:相对 dom,选取一个 dom,作为参考坐标系。以该 dom 的位置,和可视屏幕位置,结合下面的 start、end 属性,决定动画 dom 什么时候开始动画,什么时候结束动画
start:
动画 dom 开始的时机
- 参数 1: 相对 dom 的位置,例如:top | 50px | 10%;
- 参数 2: 屏幕的位置,例如:top | 200px | 30%
end:
动画 dom 结束的时机
- 参数 1: 相对 dom 的位置,例如:top | 50px | 10%;
- 参数 2: 屏幕的位置,例如:top | 200px | 30%
scrub:缓冲动画的延迟时间,时间越大,延迟越高。例如设置 1: 屏幕滚动 1s 后,开始执行动画。最终动画的位置与
scrub
无关,与start
、end
有关markers: 将
trigger
、start
、end
属性之间的关系,在屏幕表示出来。看不懂打开这个属性,就懂了
结合上图:当 start 标线与 scroller-start 处于相同位置,“动画 dom” 开始执行动画;当 end 标线与 scroller-end 处于相同位置,“动画 dom” 结束动画
# 稍复杂动画
gsap.timeline({ | |
scrollTrigger: { | |
trigger: '#page2', | |
start: 'top top', | |
end: 'bottom top', | |
scrub: 0.1, | |
pin: true, | |
} | |
}) | |
const tl2 = gsap.timeline({ | |
scrollTrigger: { | |
trigger: '#page2 .target2', | |
start: 'top top', | |
end: 'bottom top', | |
scrub: 0.1, | |
markers: true | |
} | |
}) | |
tl2.fromTo('#page2 .img3', { x: 0 }, { x: 600, rotateZ: 360, borderRadius: "50%" }) | |
tl2.fromTo('#page2 .img4', { x: 800, width: 0, opacity: 0 }, { width: 250, x: 400, y: 200, opacity: 1 }) | |
tl2.fromTo('#page2 .img5', { x: 500, y: 350, width: 0 }, { width: 1000, x: 0, y: 100 }) | |
tl2.to('#page2 .img5', { x: 100, y: 600, width: 300, borderRadius: '50%' }) |
# demo 链接
# 结语
希望看完这篇文章,可以让你对 GSAP 有个整体感知,能够知道这是个什么东西,能够做什么。如果,文章能让你快速上手,那是最好不过了。
转自:https://juejin.cn/post/7224402365452910650...