requestAnimationFrame以递归方式调用自身,如何触发动画结束事件一次?

时间:2018-04-24 13:31:45

标签: javascript recursion requestanimationframe

我试图一个接一个地重复执行相同的动画。 这里是requestAnimationFrame包装函数和区间处理函数:

Animator.prototype.animationFrame = function (options) {
    var requestAnimFrame =  requestAnimationFrame ||
                        webkitRequestAnimationFrame ||
                        mozRequestAnimationFrame ||
                        msRequestAnimationFrame ||
                        function (callback) {return setTimeout(callback, 1000/60);},
        cancelAnimFrame = cancelAnimationFrame || mozCancelAnimationFrame,
        start = performance.now();

    var interval = requestAnimFrame(function animate(time) {

        var timeFraction = (time - start) / options.duration;
        if (timeFraction > 1) timeFraction = 1;

        var progress = options.timing(timeFraction);

        options.draw(progress);

        if (timeFraction < 1) {
            requestAnimFrame(animate);
        }else{
            cancelAnimFrame(interval);
            return options.callback();
        }
    });};

回调函数正在调用动画的所有递归调用,我的目标是在重新启动动画后再触发一次回调。

调用动画将是这样的:

this.animationFrame({
        duration: 3000,
        timing: function linear(timeFraction) {
            return timeFraction;
        },
        draw: function(progress) {
            var result = to * progress;
            element.innerText = text.substr(0, Math.ceil(result))
        },
        callback: function () {
            self.clearStyles(self._wrapper);
            setTimeout(function () {
                self.startAnimations();
            }, 1000);
        }
    });

如果需要工作示例,我将根据请求提供。提前谢谢。

1 个答案:

答案 0 :(得分:0)

我使用了标志self.frameAnimationActive来指定是否需要调用动画帧。而问题的根源是,在我的情况下,animationFrame()正在调用transitionend对所有过渡的财产开火。这就是为什么我有多个animationFrame()电话。

Animator.prototype.animationFrame = function (options) {
  var requestAnimFrame =  requestAnimationFrame ||
                          webkitRequestAnimationFrame ||
                          mozRequestAnimationFrame ||
                          msRequestAnimationFrame ||
                          function (callback) {return setTimeout(callback, 1000/60);},
      self = this;
      self.frameAnimationActive = true;
      self.frameStart = performance.now();


  var mainFunction = function (params) {
      var timeFraction = (params.time - self.frameStart) / options.duration;

      if (timeFraction >= 1){
          if (self.frameAnimationActive) self.adUnit._trigger(new Event('textTypeFinished'));
          self.frameAnimationActive = false;
          timeFraction = 0;
          self.frameStart = params.time;
          options.callback();
      }

      if(self.frameAnimationActive){
          var progress = options.timing(timeFraction);

          options.draw(progress);

          requestAnimFrame(function (time) {
              params.time = time;
              return mainFunction.call(this, params);
          });
      }
  };
  mainFunction({time: performance.now()});
};