GSAP动画控制中常用的getter-setter方法

所谓getter-setter方法,就是既可以读取状态,又可以设置状态的一组方法。

.paused( )

animation.paused(true);             //设置动画状态为暂停
console.log(animation.paused());    //读取动画状态:是否在播放中?

.progress( )

animation.progress(0.5).pause();    //设置动画跳转到一半进度并暂停
console.log(animation.progress());  //读取动画播放进度。(0-1之间的值)

.time( )

animation.time(2);                  //设置跳转到第2秒
console.log(animation.time());      //读取当前播放的时间

.duration( )

animation.duration(3);              //设置总播放时长为3秒
console.log(animation.duration());  //读取动画总时长

.timeScale( )

animation.timeScale(1.5);           //设置动画1.5倍速播放
console.log(animation.timeScale()); //读取动画当前播放倍速

.reversed( )

animation.reversed(true);           //设置动画反向播放
console.log(animation.reversed());  //读取动画当前是否为反向播放

GSAP中的Callback回调函数

GSAP动画控制中常用的用于指定回调函数的属性

  • onComplete:动画播放完成时执行
  • onRepeat:动画一旦开始重播时执行
  • onReverseComplete:反向播放至起点时执行
  • onStart:播放时间一旦从0开始变动,就开始执行
  • onUpdate:随着播放进度更新即时调用

回调函数不要加(),否则会立即执行,而不是在预期的时间点开始执行。

此外,还可以给回调函数传入匹配的参数:该属性通常为一个数组的形式:[ ]。

  • onCompleteParams
  • onRepeatParams
  • onReverseCompleteParams
  • onStartParams
  • onUpdateParams
//设置回调函数及其参数
gsap.to(".class", {x:100, onComplete:myFunction, onCompleteParams:["param1", "param2"]});

回调函数的作用域

GSAP回调函数的作用域是动画本身。也就是说,函数内的this是tween对象。例如:this.targets()[0]代表第一个动画对象的Dom元素。

当使用箭头函数作为回调函数时,其作用域是箭头函数自身,而不是tween对象。所以箭头函数中的this获取不到动画的信息。

GSAP中还可以设置一个额外的callbackScope属性,用来改变默认的回调函数作用域。

class Demo {
  constructor(){
    this.animation = gsap.to(".xx",{x:100, onComplete:onComplete, callbackScope:this });
    this.message = "Hello demo";
    function onComplete(){
      console.log(this.message);
      console.log(this.animation.duration());
    }
  }
}
let demo1 = new Demo();                //"Hello demo"  0.5(获取到了默认动画时间)

举个例子:实现一个智能的动画播放控制按钮

这里希望通过一个按钮实现动画的播放控制:动画播放时,该按钮为【pause】,点击它动画停止播放。此时按钮变成【play】。动画播放结束时,按钮自动变为【pause】,再点击它,动画restart。

let select = e => document.querySelector(e);
let pause = select("#pause");                           //动画控制播放控制按钮
let animation = gsap.to(".target", {
  duration:3,
  onComplete: () => pause.innerHTML = "play"            //播放完成更改按钮文字
});

pause.addEventListener("click", ()=> {
  animation.paused(!animation.paused());                //每次点击按钮,均toggle动画paused状态
  if(animation.progress() == 1){                        //根据progress读取是否播放结束
    animation.restart();
  }
  setBtnState();                                        //执行更改按钮文字
})

function setBtnState(){
  pause.innerHTML = animation.paused() ? "play" : "pause";   //根据暂停状态更改按钮文本
}

又一个例子:给动画添加一个可以拖拽控制的进度条和时间指示器

可以使用如下input元素模拟一个进度条,我们希望动画播放时,这个进度条随之更新进度,并且当手动拖动进度条时,动画可以跳转到相应位置。而时间指示器随时显示当前播放时间。

手动调整进度条后,我们还希望动画可以暂停在这个进度,所以播放控制按钮也应当更新提示文本。

<input id="progressSlider" type="range" min="0" max="1" value="0" step="0.001" />
<div id="time">0.00</div>
progressSlider.addEventListener("input", function () {
  animation.progress(this.value).pause();        //拖动进度条时将其value值设为动画的进度
});

progressSlider.addEventListener("change", function () {
  pause.innerHTML = "play";                      //每次松开进度条,就调整按钮文字
});

//动画onUpdate时调用的回调函数
function animationUpdate() {
  progressSlider.value = animation.progress();   //动画播放过程中随时同步进度条进度
  time.innerHTML = this.time().toFixed(2);       //实时更新播放时间,并保留两位小数
}

改变一段动画的播放进度属性

将一段动画作为第一个参数传入一段tween,可以打破一个已设定好的按部就班的节奏,站在更高次元从上帝视角更魔幻的操作这些动画片段小崽子。

gsap.to(animation,{time:3})                      //先跳到动画第三秒(默认0.5秒),随后继续播放
gsap.to(animation,{time:3, duration:2})          //跳转到animation的第三秒(用时2秒)

gasp.to(animation,{timeScale:5, delay:2})        //先正常播2s,随后5倍速播放
gasp.to(animation,{timeScale:0, delay:2})        //先正常播2s,随后停止

//还可以使用progress,让动画在指定时间,按照指定时间函数转跳到指定进度
stepBtn1.addEventListener("click", ()=>{
  animation.pause();
  gsap.to(animation,{
    progress:0.5,
    duration:1,
    ease:"bounce",
    onComplate:setBtnState
  });
});