requestAnimationFrame вызывает себя рекурсивно, как можно вызвать событие завершения анимации один раз? - PullRequest
0 голосов
/ 24 апреля 2018

Я пытаюсь выполнять одну и ту же анимацию несколько раз один за другим. Вот функция оболочки 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 голосов
/ 04 мая 2018

Я использовал флаг 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()});
};
...