gsap使用教程

4,421 阅读8分钟

gsap

GSAP 是一个强大的 JavaScript 工具集,让大家秒变动画大佬。构建适用于所有主流浏览器的高性能动画。动画 CSS、SVG、画布、React、Vue、WebGL、颜色、字符串、运动路径、通用对象...... JavaScript 可以触摸的任何东西!GSAP 的ScrollTriggeropen in new window插件让您可以用最少的代码创建滚动动画。

安装引入

  1. 安装

    // npm、pnpm安装
    npm install gsap
    // yarn安装
    yarn add gsap
    
  2. 引入

    import gsap from "gsap";
    

创建动画

  • 语法 gsap.Methods(target,variables)

    • Methods:动画方式
    • target:参与动画的元素
    • variables:参数配置
  • 动画方式:.to()、.from().fromTo().set()

    • gsap.to() :最常使用的,元素从当前状态到定义状态的动画

      gsap.to(".box", { x: 200 })
      

      请添加图片描述

    • gsap.from() :与 gsap.to() 相反,元素从定义状态到初始状态的动画

      gsap.from(".box", { x: 200 })
      

      请添加图片描述

    • gsap.fromTo() :定义开始动画和结束动画

      gsap.fromTo(".box", { x: -40, backgroundColor: 'blue', }, { x: 40, backgroundColor: 'green' });
      

      请添加图片描述

    • gsap.set() :直接到定义的结束状态、无动画

      gsap.set(".box", { x: 200 })
      

      请添加图片描述

变量参数

  • target获取

    • 使用选择器或者获取的dom元素,甚至一个包含多个dom元素数组

      gsap.to(".box",{x:20});
      
      let box = document.querySelector(".box");
      gsap.to(box,{x:20});
      
      let box1 = document.querySelector(".box1");
      let box2 = document.querySelector(".box2");
      gsap.to([box1,box2],{x:200});
      
    • css属性(驼峰写法)

      gsap.to(".box", { 
        duration: 2,
        backgroundColor: '#8d3dae',
      });
      

      GSAP属性和css动画属性对应表

      请添加图片描述 特殊属性 请添加图片描述

    • js对象属性

      let obj = { x: 0, position: 0 }
      
      gsap.to(obj, {
          position: 200,
          duration: 2,
      })
      
  • ease参数配置

    • none 没有任何easing效果,匀速完成动画

    • Ease Types类型 :in out inout

      ease: "power1.in"
      // 从慢到快, 像重物落下
      
      ease: "power1.out"
      // 开始快,结束慢,就像一个滚动的球慢慢停下来
      
      ease: "power1.inOut"
      // 开始慢,中间快,结束慢,就像汽车加速和减速一样
      
      
    • 示例 power1、power2、power3、power4、back 请添加图片描述

时间线--TimeLine

Timeline是一个强大的排序工具,可以作为tween和其他时间线的容器,使其易于整体控制并精确管理其时间。如果没有时间线,构建复杂的序列将更加繁琐,因为您需要为每个动画使用延迟。例如:

// 无时间线 (仅用delay延时):
gsap.to("#id", { x: 100, duration: 1 });
gsap.to("#id", { y: 50, duration: 1, delay: 1 }); //wait 1s
gsap.to("#id", { opacity: 0, duration: 1, delay: 2 }); //wait 2s

如果你想把第一个动画做得更长呢?之后你需要调整每一次延迟。如果你想pause()暂停整个序列,或者重新restart()重新启动它,或者动态reverse()反转它或者重复两次呢?这可能会变得相当混乱,但GSAP的时间表让它变得非常简单:

// 使用WITH Timelines(更简洁、更通用)
var tl = gsap.timeline({repeat: 2, repeatDelay: 1});
tl.to("#id", {x: 100, duration: 1});
tl.to("#id", {y: 50, duration: 1});
tl.to("#id", {opacity: 0, duration: 1});

// 那么我们就可以很容易地控制整件事...
tl.pause();  //暂停
tl.resume();  //重新启动
tl.seek(1.5);  //跳转至1.5s位置
tl.reverse();  //反转
...

在时间线中定义动画

默认情况下,动画被添加到时间线的末尾,以便它们一个接一个地排序,但您可以使用位置参数来精确控制物品的放置位置。它通常位于vars参数之后,并使用具有以下选项的灵活语法:

  • 从时间线开始测量的绝对时间(秒),如3这样的数字,绿色小球等待3s后执行
 // 从时间线开始第3秒执行
tl.to(".class", { x: 100 }, 3);

在这里插入图片描述

  • <上一个动画的开始,前一个动画开始执行时执行当前动画。
// 在上一个动画的开头插入
tl.to(".class", { x: 100 }, "<");

在这里插入图片描述

  • >上一个动画的结束,前一个动画结束后执行当前动画。
// 在上一个动画结束时插入
tl.to(".class", { x: 100 }, ">");

在这里插入图片描述

  • 复杂字符串,其中+=-=前缀表示相对值。当数字跟在<>后时,它将被解释为相对值,因此<2<+=2相同。示例:
    • +=1 - 时间线末尾后 1 秒(产生间隙) 在这里插入图片描述

    • -=1 - 时间线结束前 1 秒(重叠) 在这里插入图片描述

    • <+=3 - 距离上一个动画开始已过去 3 秒

    • <3 - 与<+=3相同(见上文)(<>后面隐含+=

    • >-0.5 - 上一个动画结束前 0.5 秒。相当于说上一个动画结束时间加 -0.5

  • 基于百分比的复杂字符串。当紧跟在+=-=前缀后时,百分比基于插入动画的总时长。当紧跟在<>后时,百分比基于上一个动画的总时长。注意:总时长包括重复/溜溜球。示例:
    • -=25% - 与时间线末尾重叠 25% 的插入动画总时长。
    • +=50% - 超出时间线末尾插入动画总时长的 50%,从而产生间隙。
    • <25% - 距离上一个动画的开始位置有 25%。与>-75%相同,表示距离上一个动画的结束位置有 -75%。
    • <+=25% - 插入动画总时长在上一个动画开始之后的 25%。不同于<25%,其百分比基于上一个动画的总时长,而+=-=后面的任何内容均基于插入动画的总时长。
  • 更多效果调试

特殊属性和回调

  • 属性
//首先将一个补间动画赋值给一个变量,
let tween = gsap.to("#logo", {duration: 1, x: 100});
//暂停
tween.pause();
//恢复播放动画并且不改变方向
tween.resume();
//重新播放动画
tween.restart();
//反转播放方向
tween.reverse();

//跳转到特定的播放时间,不影响实例是否暂停或者反转
tween.seek(0.5);

//获取或者设置动画的进度
tween.progress(0.25);

//获取或者设置动画的时间缩放比例,这里设置减速为1/2
tween.timeScale(0.5);

//两倍速
tween.timeScale(2);

//杀死动画,并且会被垃圾回收机制回收内存
tween.kill();

// 可以采用链式编程
tween.timeScale(2).reverse();

  • 回调
    • onComplete:动画完成时调用
    • onStart:动画开始
    • onUpdate:动画更新每一帧
    • onRepeat:动画重复
    • onReverseComplete:动画反转后再次达到起点时调用

设置默认值

时间轴默认对象中的任何内容都会在创建子动画时被继承,因此如果您发现自己一遍又一遍地设置相同的轻松度或持续时间(或任何值),这可以帮助您的代码更简洁。例如:

// 没有默认值,如 duration、ease 属性,每个子动画都需要重复书写
var tl = gsap.timeline();
tl.to(".class1", { rotation: -270, duration: 1, ease: "elastic" })
  .to(".class2", { rotation: -360, duration: 1, ease: "elastic" })
  .to(".class3", { rotation: -180, duration: 1, ease: "elastic" });

// 有默认值,将 duration、ease 属性设置为默认值
var tl = gsap.timeline({ defaults: { duration: 1, ease: "elastic" } });
tl.to(".class1", { rotation: -270 }) //子动画继承 duration和ease 属性
  .to(".class2", { rotation: -360 })
  .to(".class3", { rotation: -180 });

通过这种方式设置的任何默认值都会被推送到每个子补间中 - 它不限于特定的属性子集。只要在子动画上声明属性,继承的默认值就很容易被覆盖。

嵌套

根据需要将时间轴嵌套在时间轴中。这样可以模块化代码并使其更易于维护。例如,您可以分段构建动画,然后将它们拼接在主时间轴中,如下所示:

function intro() {
  var tl = gsap.timeline();
  //...add animations here...
  return tl;
}

function middle() {
  var tl = gsap.timeline();
  //...add animations here...
  return tl;
}

function conclusion() {
  var tl = gsap.timeline();
  //...add animations here...
  return tl;
}

// 在主时间轴中将它们拼接在一起......
var master = gsap.timeline();
master
  .add(intro())
  .add(middle(), "+=2") // 间隔 2 秒
  .add(conclusion(), "-=1"); // 重叠1秒

其他时间轴功能

  • 使用其 timeScale() 方法加速或减慢整个时间轴。您甚至可以对其进行补间,以平滑地逐渐加速或减慢动画!
  • 使用其 progress()totalProgress() 方法获取或设置时间线的进度(totalProgress() 仅包括任何重复)。例如,要跳到中间点,请设置 myTimeline.progress(0.5)
  • 使 time()totalTime()progress() 或 totalProgress() 进行补间,以快进或倒退时间线。您甚至可以将滑块附加到其中一个,让用户能够在时间线上向前或向后拖动。
  • 使用构造函数的 vars 对象(如 var tl = gsap.timeline({onComplete: myFunction}))添加 onCompleteonStartonUpdateonRepeatonReverseComplete 回调。
  • 使用 killTweensOf(target) 终止时间轴内特定对象的补间,或使用 getTweensOf() 获取对象的补间,或使用 getChildren() 获取时间轴内的所有补间和时间轴。
  • 将时间线设置为重复任意次数或无限次。您甚至可以设置每个重复周期之间的延迟和/或使重复周期来回摆动,每隔一个周期就会反转方向。
  • 获取 currentLabel() 或使用 nextLabel()previousLabel() 查找时间轴中各个位置的标签。
  • 示例如下:
// 创建重复 3 次、每次重复间隔 1 秒的时间轴,然后在完成时调用 myFunction()
var tl = gsap.timeline({ repeat: 3, repeatDelay: 1, onComplete: myFunction });

// 添加补间动画
tl.to(".class", { duration: 1, x: 200, y: 100 });

// 在时间轴结束后 0.5 秒添加另一个补间(使排序变得简单)
tl.to("#id", { duration: 0.8, opacity: 0 }, "+=0.5");

// 反转
tl.reverse();

// 在时间线 3 秒处添加“旋转”标签
tl.addLabel("spin", 3);

// 在“旋转”标签处插入旋转补间(您也可以将插入点定义为时间而不是标签)
tl.to(".class", { duration: 2, rotation: "+=360" }, "spin");

// 转到“旋转”标签并从那里播放时间线
tl.play("spin");

// 在时间线内嵌套另一个时间线...
var nested = gsap.timeline();
nested.to(".class2", { duration: 1, x: 200 });
tl.add(nested, "+=3"); // 在 3 秒间隔后添加嵌套时间线