以下内容是个整体功能的描述,不会对所有 api 进行说明讲解,主要是关键性内容描述。

# 前言

作为一个前端开发,不可避免地需要开发动画。如果自己临时写一个动画,还是比较容易出问题的,今天介绍一个很好用的动画库,功能十分强悍 ———— GSAP。

# 效果

说再多,也不如直接来效果来的直观。
如果能科学上网可以查看以下官网链接:

  1. GSAP 动画:greensock.com/showcase/
  2. GSAP ScrollTrigger(gsap 的插件)动画:greensock.com/st-demos/

# GSAP

# 安装 && 基础 api

# 安装

pnpm install gsap (其他方式也行,注意:在 vue、react 等框架下使用,应在 dom 渲染后调用)

# to:

  1. 代码: gsap.to(目标dom, { x: 300, y: 100, duration: 1, ease: 'back' })
  2. 效果说明:目标 dom,translate (300px,100px),持续过程 1s,过渡动画:back(后面讲解)
  3. 效果:04e7b486-eeed-49a9-bc9b-07f7c8efb5f6.gif

# from:

  1. 代码: gsap.from(目标dom, { x: 300, duration: 1, delay: 1 })
  2. 效果说明:目标 dom,初始化 translateX (300px),然后回到原本代码的位置,持续过程 1s,延长 1s 执行
  3. 效果:33a7232d-411d-41cb-9243-d580c9be71db.gif

# fromTo:

  1. 代码: gsap.fromTo(目标dom, { x: 300, y: 100 }, { x: 100, y: 50 })
  2. 效果说明:目标 dom,初始化 translate (300px, 100px),去往 translateX (100px, 50px),持续过程:默认时间
  3. 效果:00eb21f5-99df-4a31-b5fa-0c6ecbf6f90e.gif

# 常用参数说明

例如: gsap.to(to.value, { x: 300, y: 100 }) ,参数是:x、y

# 参数列表

  1. keyframes:类似 css 的 keyframes,执行多段动画,例如: gsap.to(目标dom, { keyframes: [{x: 100}, {y: 100}] })
  2. esae:缓冲动画函数。img
  3. x、y:移动到 x、y 的位置,对应 api:translate
  4. duration: 动画持续时间,单位: s
  5. delay:动画延迟执行,单位:s
  6. repeat:重复执行动画,单位:次,无限次数则:-1
  7. yoyo:是否原路返回执行,配合 repeat 使用。例如:yoyo: false,执行:1-2-3-1-2-3-1-2-3;则,yoyo:true,执行效果:1-2-3-3-2-1-1-2-3
  8. repeatDelay: repeat 延迟执行,单位:s
  9. 其他:top、left、borderSize、borderRaduis、width、height 等 css 属性

# Hooks

  1. onComplete:动画执行完成回调;回调函数的参数:onCompleteParams: any []
  2. onRepeat:动画重复执行回调;回调函数的参数:onRepeatParams: any []
  3. 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. 效果:3cc9555c-28a6-44a4-8fc4-b4f8ca740b04.gif

# 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})

20230421-110639.gif

# 时间轴定义

# 默认序列

20230421-113338.gif

# 相对序列

20230421-113435.gif 20230421-113509.gif

# 绝对序列

20230421-113538.gif

# label 序列

20230421-113607.gif

# 常用参数

  1. repeat: 时间轴动画重复次数,类型 number
  2. repeatDelay: 重复动画间隔时间(以秒为单位),类型 number
  3. yoyo:重复动画交替方式,类型 boolean(同上文 yoyo)
  4. delay:时间轴开始之前的延迟(以秒为单位),类型 number
  5. reversed:时间轴动画是否倒放,类型 boolean
  6. onComplete: 时间轴动画完成回调,类型 (...args: any []) => void | null
  7. onRepeat:时间轴动画重复执行回调,类型 (...args: any []) => void | null
  8. onStart: 时间轴动画开始执行回调,类型 (...args: any []) => void | null
  9. onUpdate:时间轴动画运行时回调,类型 (...args: any []) => void | null
  10. 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()
        }
    })

20230421-110639.gif

  1. tl.pause (): 暂停动画
  2. tl.reverse (): 反向播放动画
  3. tl.add (): 添加补间动画(对比上面和下面的 timeline 例子)
  4. 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'))
  1. tl.seek (): 跳到指定的时间
const tl = gsap.timeLine()
tl.seek(1) // 跳到 1 秒初
tl.seek('+=1') // 相对时间,当时时间 + 1
tl.seek('label') // 跳到指定标签处 (应先添加 label)
  1. tl.progress (): 进度跳转在 0~1 之间
  2. tl.kill (): 杀死动画
  3. tl.to
  4. tl.from
  5. ......

# 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 的参数集,以下对上面代码的参数集进行解释:

  1. trigger:相对 dom,选取一个 dom,作为参考坐标系。以该 dom 的位置,和可视屏幕位置,结合下面的 start、end 属性,决定动画 dom 什么时候开始动画,什么时候结束动画

  2. start:

    动画 dom 开始的时机

    1. 参数 1: 相对 dom 的位置,例如:top | 50px | 10%;
    2. 参数 2: 屏幕的位置,例如:top | 200px | 30%
  3. end:

    动画 dom 结束的时机

    1. 参数 1: 相对 dom 的位置,例如:top | 50px | 10%;
    2. 参数 2: 屏幕的位置,例如:top | 200px | 30%
  4. scrub:缓冲动画的延迟时间,时间越大,延迟越高。例如设置 1: 屏幕滚动 1s 后,开始执行动画。最终动画的位置与 scrub 无关,与 startend 有关

  5. markers: 将 triggerstartend 属性之间的关系,在屏幕表示出来。看不懂打开这个属性,就懂了

image.png

结合上图:当 start 标线与 scroller-start 处于相同位置,“动画 dom” 开始执行动画;当 end 标线与 scroller-end 处于相同位置,“动画 dom” 结束动画

20230421-153544.gif

# 稍复杂动画

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%' })

20230421-161920.gif

# demo 链接

github.com/goodrufu/gs…

# 结语

希望看完这篇文章,可以让你对 GSAP 有个整体感知,能够知道这是个什么东西,能够做什么。如果,文章能让你快速上手,那是最好不过了。

转自:https://juejin.cn/post/7224402365452910650...