GSAP动画库——如何高效写动画

GSAP动画学习——来自GSAP中文文档

如何高效的制作动画

1.使用一个动画库

使用GSAP动画库可以解决的问题:

  • 浏览器错误、不一致性和兼容性
  • 不仅仅是DOM的动画:Canvas、WebGL、通用对象和复杂字符串不能使用原生技术进行动画处理。对于所有动画使用一个一致的工具更加简洁。
  • 运行时候控制:可以在运行的时候独立的控制每个变化的组件,简单来说就是这几个API
  • 缓动选项(弹跳,弹性等)
  • 延迟平滑:如果CPU变慢,GSAP可以优先考虑绝对时间或即时调整以避免动画卡顿跳跃。
  • 高级功能:使用GSAP,很容易就可以变形SVG、添加物理/惯性、直接在浏览器中编辑运动路径、使用位置感知的交错动画等等。

2.时间线的使用

在GSAP中,实现动画的顺序执行可以使用到时间线,最后一个参数中是动画的执行时机

  • 加数字,例如1,则是在时间线的1秒开始执行
  • <, 在上一个动画开始时插入,相当于把动画变成指向上一个动画开头的指针
  • >, 在上一个动画结束后插入,相当于把动画变成指向上一个动画结束的指针
  • +=1,在上一个动画结束后的1秒后播放这个动画
const tl = gsap.timeline(); 
tl.to(".box", { duration: 1, x: 100 })
  .to(".box", { duration: 1, backgroundColor: "#f38630" }, "+=0.5") 
  .to(".box", { duration: 1, x: 0, rotation: -360 }, "+=0.5")

演示demo1

3.相对值的使用

GSAP识别+= 和 -= 前缀

x:"+=200”将在当前x的基础上添加200个单位(通常是像素)。而x:“-=200”将从当前值中减去200。

当值需要响应视口大小更改时,请使用相对单位(如vw,vh和在某些情况下为%)
尽可能使用.to()和.from()方法(而不是.fromTo())

4.关键帧的使用

如果你的动画效果需要循环往复,这个时候就用关键帧吧

gsap.to(".box", { keyframes: [
  { duration: 1, x: 100 },
  { duration: 1, backgroundColor: "#f38630", delay: 0.5 }, 
  { duration: 1, x: 0, rotation: -360, delay: 0.5 }
]});

演示demo2

这样可以不用使用时间线动画,通过delay的设置让每一个动画效果之间产生间隔(设置负数就会重叠)

关键帧的使用看起来会比timeline的简洁得多,比如下面这段代码:

// 使用timeline
let tl = gsap.timeline();
tl.to(".box", {
    x: 100
  })
  .to(".box", {
    y: 100
  })
  .to(".box", {
    x: 0
  })
  .to(".box", {
    y: 0
  });
// 用数组的方式
gsap.to(".box", {
  keyframes: {
    x: [0, 100, 100, 0, 0],
    y: [0, 0, 100, 100, 0],
    ease: "power1.inOut"
  },
  duration: 2
});
关键帧中的参数
gsap.to(".elem", {
 keyframes: [ // 注意这里是数组
  {x: 100, duration: 1, ease: 'sine.out'}, // 定义这个分段动画自己的ease曲线
  {y: 200, duration: 1, delay: 0.5}, // 产生和前个分段动画0.5秒的间隔
  {rotation: 360, duration: 2, delay: -0.25} // 和前一个分段动画产生0.25秒的重叠
 ],
 ease: 'expo.inOut' // 设置整个关键帧动画的曲线
});

关键帧动画的默认动画曲线是线性的,也就是线性匀速的动画,你可以在每个动画中都重新定义ease的设置,你也可以给整个关键帧动画添加一个统一的的动画曲线设置。

使用Percentage
gsap.to(".elem", {
 keyframes: {  // 注意这里是对象
  "0%":   { x: 100, y: 100},
  "75%":  { x: 0, y: 0, ease: 'sine.out'}, // 指定这个分段的动画曲线
  "100%": { x: 50, y: 50 },
   easeEach: 'expo.inOut' // 每个分段的动画曲线
 },
 ease: 'none' // 整个关键帧动画的动画曲线
 duration: 2,
})

这样的写法,默认的ease曲线是power1.inout,这个曲线看起来的整个变化效果是不错的,但是如果你想要指定每个分段变化的动画曲线,你可以通过每个分段动画内部的ease曲线,或者也可以通过easeEach属性来设置。

这个写法和CSS中的关键帧动画的写法是很类似的。 不需要给每一段动画单独设置时长和延时,只要给整体设置一个时长,然后确定每个分段动画的时间比例。

使用数组的方式编写关键帧
gsap.to(".elem", {
 keyframes: { // 注意这里是对象
  x: [100, 0, 50], // 数组分段,也就是两段动画,100-0,,0-50
  y: [100, 0, 50]
  easeEach: 'sine.inOut' // 每个分段都设置成这个动画曲线
  ease: 'expo.out' // 关键帧整体的动画曲线设置
 },
 duration: 2, // 总时长2秒,这里有两段,平均分就是每段的时长是1秒
})

通过数组的方式,各个分段自动平均分总时长。

这样的写法,默认的ease曲线是power1.inout,或者也可以通过easeEach属性来设置所有分段的ease曲线。

5.在使用动画之前提前设置好默认值

GSAP有默认值,例如ease(“power1.out”)和duration(0.5秒)等属性。

GSAP可以改变全局的默认设置,使用gsap.default()进行设置

// 使用线性缓动曲线 和 1秒的动画时长
gsap.defaults({ ease: "none", duration: 1 });

6.同时驱动多个元素

可以使用更复杂的选择器字符串选择具有不同选择器的多个元素:

gsap.to(".box, .circle", { ... });

或者,只要是相同类型(选择器字符串,变量引用,通用对象等),您就可以传递使用数组进行一起传递:

var box = document.querySelector(".box");
var circle = document.querySelector(".circle");

// some time later…
gsap.to([box, circle], { ... });

7.使用基于函数的值、stagger、loop

基于函数的值:

可以根据函数的任何内容作为属性值

var yMove = 50;
gsap.to(".box", {
  delay: 0.5,
  duration: 1,
  // 第一个参数是当前节点索引 第二个是当前节点 第三个是节点列表
  y: function(index, elem, boxes) {
    return index % 2 === 1 ? -yMove : yMove;
  }
});

演示demo3

或者可以从数组中选择元素:

var colors = ["#3498db", "#27ae60", "#f1c40f"];
gsap.to(".box", {
  delay: 0.5,
  duration: 1,
  backgroundColor: function(i, elem, boxes) {
    return colors[i % 3];
  }
});

演示demo4

Staggers

通过使用stagger来偏移动画的开始时间,使其看起来更加动态和有趣。对于单个动画中的简单间隔偏移,只需使用stagger:0.2即可在每个动画的开始时间之间添加0.2秒

var yMove = 50;
gsap.to(".box", {
  delay: 0.5,
  duration: 1,
  stagger: 0.2,
  y: function(index, target, list) {
    // 第一个参数是索引 第二个是当前元素 第三个是元素列表
    return index % 2 === 1 ? -yMove : yMove;
  }
});

演示demo5

同时在stagger的值可以是一个对象,给每一个动画设置一定的效果

gsap.to(".box", {
  y: 100,
  stagger: { // 将高级选项包裹在对象中
    each: 0.1,
    from: "center",
    grid: "auto",
    ease: "power2.inOut",
    repeat: -1 ,// 立即重复播放,不需要等待其他的动画结束
    yoyo:'true',
  }
});

还可以传递一个对象获得更复杂的stagger效果,下面是stagger文档里面的demo,关于GSAP的更多信息可以查看stagger文档

演示demo6

LOOP循环

要循环遍历元素,最简单的方法是使用.forEach()。但是由于IE不支持在使用.querySelectorAll()选择的元素上使用.forEach(),因此可以改用GSAP的utils.toArray()函数。

// toArray:将几乎任何类似数组的对象转换为数组,包括选择器文本!
gsap.utils.toArray(".container").forEach((container, i) => {
  const header = container.querySelector("h1");
  const content = container.querySelector(".content");
  gsap.to([header, content], {autoAlpha: 1, duration: 0.5, stagger: 1, delay: i * 2});
});

演示demo7

8.模块化你的动画

Function函数

将动画效果提前封装好调用,将它们组合成更大的程序,同时保持代码整洁、可重用和易于修改,增加代码的可重用性。

function doAnimation() {
  // 可以进行一些处理,比如计算,使用传入该函数的参数数据

	// r返回一个tween,可以使用上面计算后的数据
  return gsap.to(".myElem", { duration: 1, color: "red"});
}
tl.add( doAnimation() );使用嵌套的时间线方式可以改变动画组织逻辑。能让你轻松的实现各种复杂的逻辑动画。
function doAnimation() {
  const tl = gsap.timeline();
  tl.to(...);
  tl.to(...);
  // 可以添加任意多的动画效果

  // 结束之后返回时间线实例
  return tl;
}

const master = gsap.timeline();
master.add( doAnimation() );
master.add( doAnotherAnimation() );
// 可以添加更多的时间线

演示demo8

将动画构建例程包装在函数中,还可以使重新创建动画,下面是在调整窗口时候重新创建动画

var tl; // 设置一个引用,可以访问到时间线实例

function buildAnimation() {
  var time = tl ? tl.time() : 0; // 储存实例动画已经进行了多长的时间

  // 如果实例已经存在,就销毁它
  if (tl) {
    tl.kill();
  }

  // 创建一个新的时间线实例
  tl = gsap.timeline();
  tl.to(...)
    .to(...); // 开始动画
  tl.time(time); // 把动画时间线设置到它已经进行到的位置
}

buildAnimation(); // 启动

window.addEventListener("resize", buildAnimation); // 处理浏览器窗口变化
Effects效果

使用效果可以自定义动画转换为一个命名效果,可以随时使用新的目标的配置调用它。你对动画有标准或者如果你将从不同的上下文中调用相同的动画时,这将非常有帮助。

下面是一个简单的“淡入淡出的效果”

// 在GSAP上注册effect:
gsap.registerEffect({
    name: "fade",
    defaults: {duration: 2}, // 在这个defaults设置的数据可以通过下方的config参数获取到进行设置
    effect: (targets, config) => {
        return gsap.to(targets, {duration: config.duration, opacity:0});
    }
});

// 然后我们可以这样使用了:
gsap.effects.fade(".box");
//或者还可以把默认的设置覆盖掉:
gsap.effects.fade(".box", {duration: 1});

演示demo9

9.使用control方法

GSAP 提供了许多控制补间或时间线状态的方法。它们包括 .play()、.pause()、.reverse()、.progress()、.seek()、.restart()、.timeScale() 等等。

使用控制方法可以使动画之间的过渡更加流畅(例如能够在部分过程中反转)并且更高效(通过重用相同的补间/时间线而不是每次创建新实例)。

let nav = document.querySelector('.nav')

let tween = gsap.to(".purple", {
  duration: 4, 
  x: () => nav.offsetWidth, // animate by the px width of the nav
  xPercent: -100, // offset by the width of the box
  rotation: 360, 
  ease: "none", 
  paused: true
});

// click handlers for controlling the tween instance...
document.querySelector("#play").onclick = () => tween.play();
document.querySelector("#pause").onclick = () => tween.pause();
document.querySelector("#resume").onclick = () => tween.resume();
document.querySelector("#reverse").onclick = () => tween.reverse();
document.querySelector("#restart").onclick = () => tween.restart();

演示demo10

下面是一个控制timeScale来控制时间线动画来实现的效果:在鼠标悬浮在节点的时候会减缓速度,timeScale的效果可以理解为会使得原来的duration = duration/timScale。

const tl = gsap.timeline(),
    atom = document.querySelector(".atom"),
    dur = 2,
    del = 0.5;

const e = tl.fromTo('.electron', {rotationX: 90}, {
  rotationZ: -360,
  rotationX: 90,
  ease: 'none',
  duration: dur,
  stagger: {
    each: -del,
    repeat: -1
  }
}, 0);
const p = tl.to('.path', {
  rotationZ: 360,
  ease: 'none',
  duration: dur,
  stagger: {
    each: -del,
    repeat: -1
  }
}, 0);

// Add a rotation to the whole atom
gsap.set(atom, {transformOrigin: "center center"});
gsap.to(atom, {rotation: 360, ease: "none", repeat: -1, duration: 300})

// Skip the loading
tl.progress(0.9999);

const timeScaleTween = gsap.to(tl, {
  duration: 0.75,   
  timeScale: 0.1,
  paused: true
});

// Slow the animation on mouse enter
atom.addEventListener("mouseenter", function() {
  timeScaleTween.play();
});
// Set the animation back to normal on mouse leave
atom.addEventListener("mouseleave", function() {
  timeScaleTween.reverse();
});

演示demo11

案例:交互事件触发动画

在下面的示例中,我们为每个元素创建一个时间线动画(以便不会在所有实例上触发相同的动画),将该时间轴的引用附加到元素本身,然后在悬停元素时播放相关的时间轴,在鼠标离开时反转它。

gsap.set(".information", {yPercent: 100});
gsap.utils.toArray(".container").forEach(container => {
  let info = container.querySelector(".information"),
      silhouette = container.querySelector(".silhouette .cover"),
      tl = gsap.timeline({ paused: true });
  
  tl.to(info, { yPercent: 0 })
    .to(silhouette, { opacity: 0 }, 0);
  
  container.addEventListener("mouseenter", () => tl.play() );
  container.addEventListener("mouseleave", () => tl.reverse() );
});

演示demo12

案例:在时间线上多个状态之间实现变化

下面的案例中,一个元素中有两种动画效果,鼠标悬浮在元素上,在点击元素之前是三条线变成六边形,在点击后是透明度的变化,再次点击再变回三条线。

// 初始化数据
const menu_dur = 0.3,
      menu_btn_anim = gsap.timeline({paused: true, defaults: {duration: menu_dur}}),
      menu_btn = document.querySelector(".menu_button");
// 第一个动画,使用svg画三条线
menu_btn_anim
  .to("#x_left", {drawSVG:"0%"}, 0)
  .fromTo("#top_right,#middle_left, #middle_right, #bottom_left", {autoAlpha:1, drawSVG:"0%"}, {drawSVG:"100%"}, 0)
// 第二个动画,一个叫hover的动画 在下面会调用,作用是将三条线变为一个叉
  .addLabel("hover")
  .to("#x_right, #x_left", {autoAlpha:1, drawSVG:"100%"}, "hover")
  .to(["#top_right,#middle_left, #middle_right, #bottom_left", "#top_left", "#bottom_right"], {drawSVG:"0%"}, "hover")

menu_btn.addEventListener("mouseenter", function() {
  if(!isClicked) {
    // tweenTo:创建一个线性补间,本质上将播放头拖动到特定时间或标签,然后停止。
    menu_btn_anim.tweenTo("hover");
  // 在本例中tweenTo的作用是 将hover的动画播放头拖回到开始
  } else {
    gsap.to(menu_btn, {duration: menu_dur, autoAlpha: 0.4});
  }
});

menu_btn.addEventListener("mouseleave", function() {
  if(!isClicked) {
    menu_btn_anim.reverse();
  } else {
    gsap.to(menu_btn, {duration: menu_dur, autoAlpha: 1});
  }
});
 
var isClicked = false;
menu_btn.addEventListener("click", function() {
  if(!isClicked) {
    // 点击之前 btn的动画是menu_btn_anim
    menu_btn_anim.play();
    gsap.to(menu_btn, {duration: menu_dur, autoAlpha: 0.4});
  } else {
    // 将hover的动画播放头拖回到开始
    menu_btn_anim.tweenTo("hover");
    gsap.to(menu_btn, {duration: menu_dur, autoAlpha: 1});
  }
  isClicked = !isClicked;
});

演示demo13

案例:基于滚动位置的动画

此演示在到达滚动位置后播放完整动画:

const tl = gsap.timeline({paused: true});
tl.from("h1", {scale: 0.7, autoAlpha: 0, duration: 1});

function animateAtScrollPos() {
  if(scrollY > 100) {
    tl.play();
    document.removeEventListener("scroll", animateAtScrollPos);
  }
}
document.addEventListener("scroll", animateAtScrollPos);

演示demo14

稍微高级一点的效果

const tl = gsap.timeline({paused: true});
tl.from("h1", {scale: 0.7, autoAlpha: 0});
const startY = innerHeight / 10;
const finishDistance = innerHeight / 5;
function animateAtScrollPos() {
  // progress获取或设置时间线的进度,该进度是 0 到 1 之间的值,指示虚拟播放头的位置(不包括重复),其中 0 表示开始,0.5 表示完成一半,1 表示完成。
  tl.progress((scrollY - startY) / finishDistance);
}
document.addEventListener("scroll", animateAtScrollPos);

演示demo15

以上就是在中文文档中GSAP的案例的动画效果,此外,你还可以使用GSAP的插件,制作更加优美的动画效果,例如ScrollTriggerMorphSVGGSDevTools等等。

更多信息可以点击GSAP中文文档

10.GSAP中的部分API

10.1 gsap.killTweensOf()

终止特定对象的所有动画,你可以传入一个节点,这样可以销毁节点上的所有gsap动画

如果你想终止特定的动画,也可以在后面写上需要终止动画的参数,例如

gsap.killTweensOf(qc.Node,"opacity,x")

如果想要杀死所有延迟调用(例如使用gsap.delayedCall(5.myFunction),创建的调用),可以直接调用gsap.killTweensOf(myFunction),需要注意的是,即使尚未启动的动画,使用killTweensOf任然会销毁动画。(设定了一个5秒后延迟的动画,如果在两秒之后删除它,那么动画将不会执行)。

10.2 gsap.globalTimeline

gsap.globalTimeline 是驱动 GSAP 中所有内容的根时间轴实例,使其成为同时影响所有动画的强大方式。有如下有用的方法

gsap.globalTimeline.pause()

暂停影响所用动画的全局时间线 返回自身

.play()

恢复所有动画 返回自身

.paused()

如果全局时间线暂停 返回 true  否则返回 false

.timeScale()

设置全局时间刻度,会影响根时间轴的播放速率,这个时间轴包含所有其他的动画,这是一个全局加速或减慢所有动画的好方法。

gsap.globalTimeline.timeScale(0.5); // 用0.5倍速播放所有动画
gsap.globalTimeline.timeScale(2); //用 2倍速播放所有动画
var currentTimeScale = gsap.globalTimeline.timeScale(); // 返回当前全局timeScale的值
10.3 gsap.ticker

Gap.ticker 是个整个引擎的心跳, 它在每一个requestAnimationFrame 事件上更新 globalTimeline ,因此 它和浏览器的渲染周期完美同步。我们可以添加自己的侦听器,用于在每次跟新之后运行自定义逻辑。(非常适合游戏开发人员)

//添加一个侦听器
gsap.ticker.add(myFunction,once,prioritize);
// myFunction:执行逻辑函数
// 下面两个参数在GSAP 3.10.0 中才存在
// once: boolean 执行逻辑函数只会触发一次,然后自动删除
// prioritize:布尔值 - 回调将被添加到队列的顶部而不是底部,这意味着它将在队列中当前的任何侦听器之前触发。如果希望在 GSAP 的全局时间线之前触发回调,这是非常完美的选择。

function myFunction(time, deltaTime, frame) {
  // 在引擎的每一个tick跟新之后执行
 	// time:第一个tick启动后的总时间
  // deltaTime:从上一个tick 到当前tick的时间
  // frame:帧变好 在每一个刻度递增
}

//移除侦听器
gsap.ticker.remove(myFunction);
gsap.ticker.fps(60)

设置动画执行的帧率

10.4 gsap.util.toArray()

将几乎任何类似数组的对象转换为数组,包括选择器文本!(例如: toArray(".class") --> [element1, element2] )。

10.5 gsap.version

属性值 当前正在使用的gsap 版本

10.6 gsap.config()

配置非补间的GSAP设置 比如 autoSleep、force3D、units

10.7 gsap.context()

收集在提供函数中创建的所有GSAP动画 以便轻松的一次性完成所有的动画和滚动触发器的 反转 删除 revert()  kill()

let ctx = gsap.context(() => {// 收集所用的动画
 gsap.to(...);
 gsap.from(...);
 gsap.timeline().to(...).to(...);
 ...
});

ctx.revert(); // 现在每一个动画都反转了
10.8 gsap.defaults()

设置动画的默认值 比如ease duration

gsap.defaults({
  ease: "power2.in", 
  duration: 1
});
10.9 gsap.delayedCall()

一种在设定时间之后调用函数的简单方法。

//calls myFunction() after 1 second and passes 2 parameters:
gsap.delayedCall(1, myFunction, ["param1", "param2"]);

function myFunction(param1, param2) {
  //do stuff
}
10.10 gasp.exportRoot()

将所有补间、时间线和 [可选] 延迟调用从根时间线无缝传输到新时间线,以便您可以在看似全局的基础上执行高级任务,而不会影响导出后创建的补间/时间线。

例如,假设一个游戏使用GSAP进行其所有动画,并且在游戏过程中的某个时刻,您希望将所有内容减慢到停止(动画化 timeScale ),同时将新的弹出窗口动画化到位:

var tl = gsap.exportRoot();
gsap.to(tl, {duration: 0.5, timeScale: 0});
//this tween isn't affected because it's created after the export.
gsap.fromTo(myWindow, {scaleX: 0, scaleY: 0}, {duration: 1, scaleX: 1, scaleY: 1});
10.11 gsap.getById()

创建补间或时间线的时候,会分配一个id 可以引用它。对使用框架和构建工具如(react)很有帮助

gsap.to(obj, {id: "myTween", duration: 1, x: 100});

//later
let tween = gsap.getById("myTween"); //returns the tween
tween.pause();

注意: gsap会在动画完成后布局自动发布用于垃圾回收的动画,硬刺getById() 只会查找 处于活动状态 或尚未开始的动画。

10.12 gasp.getProperty()

通过id值 返回所请求属性的值

gsap.getProperty("#id", "x");              // 20 
gsap.getProperty("#id", "x", "px")         // "20px"
gsap.getProperty("#id", "backgroundColor") // "rgb(255, 128, 0)"
10.13 gsap.isTweening()

判断对象是否在进行动画处理 如果 动画已经暂、已经完成 或者尚未开始,则不会将其视为活动状态

if (!gsap.isTweening("#id")) {
  // do stuff
}
传入的参数可以是一个id 或者一个 对象
10.14 gsap.matchMedia()

一个媒体查询方法,用于在不同屏幕,实现不同的动画,每次屏幕有变化的时候都会执行这个函数,如果用户多次调整浏览器大小,则该函数会被多次调用。

基本用法:

let mm = gsap.matchMedia();

// 添加一个媒体查询,当匹配的的时候 里面的函数就会执行
mm.add("(min-width: 800px)", () => {

  // 下面的动画只有当屏幕宽度小于800px 的时候会执行
  gsap.to(...);
  gsap.from(...);
  ScrollTrigger.create({...}); 

  return () => { // 可选的
    // 在这里定义清除动画代码 内存回收
  };
});

//=============简单的桌面/移动 示例
let mm = gsap.matchMedia();

mm.add("(min-width: 800px)", () => {
  // desktop setup code here...
});

mm.add("(max-width: 799px)", () => {
  // mobile setup code here...
});
10.15 gsap.set()

立即设置目标的属性,不会以动画的方法执行,相当于修改属性

11.gsap.timeLine()

时间轴是我们常用的实现动画的方式,在构建动画的时候,我们经常会先创建一个时间轴let tl = gsap.timeline()

以下是一些时间轴的API

11.1 tl.addLable()

给时间线添加标签,以便轻松标记重要位置/时间 传入参数为字符串

//案例额
var tl = gsap.timeline();
tl.to("#green", {x:750, duration:1})
  // 我们在 时间线1s之后添加了一个标签 "blueGreenSpin"
  .addLabel("blueGreenSpin", "+=1")
  // 在标签处添加了 一个动画
  .to("#blue", {x:750, rotation:360, duration:2}, "blueGreenSpin") 
  // 在标签后的0.5s处添加了一个动画
  .to("#orange", {x:750, rotation:360, duration:2}, "blueGreenSpin+=0.5");

于是动画效果变成了

预览地址

标签的定位 和动画的定位一样,同样可以使用 “<”,“>”, “+=1”, “-=1”, 也可以直接用标签定位标签

// 在someLable标签处插入了myLable标签
tl.addLabel("myLabel", "someLabel");
11.2 tl.addPause()

用于在特定时间或者标签暂停时间轴的播放

// 在时间轴2s处暂停播放
timeline.addPause(2);

// 在标签"yourLabel"处 暂停播放
timeline.addPause("yourLabel");

// 在标签"yourLabel"后三秒暂停播放
timeline.addPause("yourLabel+=3", yourFunction);

// 在4s 处暂停播放 并执行函数 yourFunction 传入两个参数 "param1" "param2"
timeline.addPause(4, yourFunction, ["param1", "param2"]);

暂停只是一个0持续时间的补间,硬刺可以通过timeline().removePause() 删除

11.3 tl.call()

将回调添加到时间线的末尾(或使用 position 参数在其他地方),这与在时间轴本身上使用 onComplete 特殊属性不同,因为一旦附加回调,它就会保留在原位,而 an onComplete 总是在时间线的最后调用。

function myFunction(param1, param2) {
  //...
}
tl.add( gsap.delayedCall(0, myFunction, ["param1", "param2"]) );
tl.call(myFunction, ["param1", "param2"]);
11.4 tl.delay()

获取或设置动画的初始 delay 值,即动画应开始之前的时间长度(以秒为单位)。

11.5 tl.endTime()

根据父时间轴的本地时间返回动画完成的时间。会考虑timeScale对时间线的影响

var tl = gsap.timeline();

// 创建一个 1秒的动画
var tween = gsap.to(e, {duration: 1, x: 100}); 

// 在时间线0.5秒之后插入动画
tl.add(tween, 0.5); 

console.log(tween.endTime()); //1.5

// 让刚刚创建的动画 以2倍速播放 即持续时间变为0.5s
tween.timeScale(2); 

console.log(tween.endTime()); //1
11.6 tl.startTime()

获取或设置动画在其父时间轴上开始的时间(在定义的任何延迟之后)。

11.7 tl.time()

获取或设置播放头的本地位置(实质上是当前时间),不包括任何重复或重复延迟。

11.8 tl.totalTime()

根据 获取或设置播放头 totalDuration 的位置,其中包括任何重复和重复延迟。

参考资料

gsap中文教程

GSAP文档

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值