循环动画

时间:2016-03-26 19:27:30

标签: javascript html5 animation canvas

我为我正在创建的简单Canvas library创建了一个有效的动画方法,但我无法弄清楚如何制作动画循环 - 从方法本身来看,给出一个选择。我的意思是我知道如何在应用程序本身中循环它,但不仅仅是因为我将方法传递给loop参数然后它为我做了。这是动画片段:

Canvas.objects.Base.prototype.animate = function (options) {
    options.easing = Canvas.animation.easing[options.easing] || options.easing;
    options.duration = Canvas.animation.durations[options.duration] || options.duration * 1000;
    var start = Date.now(),
      total = start + options.duration,
      old = {},
      id,
      self = this;
    for (var i in options.properties) {
      if (options.properties.hasOwnProperty(i)) {
        old[i] = this[i];
      }
    }
    (function update() {
      var now = Date.now(),
        progress = Math.min((options.duration - (total - now)) / options.duration, 1);
      for (var i in options.properties) {
        if (options.properties.hasOwnProperty(i)) {
          self[i] = options.easing(now - start, old[i], options.properties[i] - old[i], options.duration);
        }
      }
      if (progress < 1) {
        id = requestAnimationFrame(update);
      } else {
        id = cancelAnimationFrame(id);
        if (options.loop) {
          var animate = function () {
            for (var j in options.properties) {
              self[j] = old[j];
            }
            if (!options.callback) {
              self.animate({
                properties: options.properties,
                easing: options.easing,
                duration: options.duration,
                callback: animate
              });
            } else {
              self.animate({
                properties: options.properties,
                easing: options.easing,
                duration: options.duration,
                callback: function() {
                  options.callback();
                  animate();
                }
              });
            }
          };
          options.callback = animate;
        }
        if (options.callback) {
          options.callback();
        }
      }
    }());
  };

现在,这是code我必须让循环在方法本身之外工作:

var animate = function () {
  circle.x = test.canvas.width / 2;
  circle.y = test.canvas.height / 2;
  circle.animate({
    properties: {
        x: test.canvas.width
    },
    easing: 'easeInOutExpo',
    duration: 1,
    callback: function () {
        circle.animate({
        properties: {
            y: test.canvas.height
        },
        easing: 'easeInOutExpo',
        duration: 1,
        callback: animate
      });
    }
  });
};

// 'animate` is called later on a click

使用我现在在方法中的代码,一旦它执行初始动画,它确实在动画之前恢复到它的所有属性,但然后坐在那里直到再次点击窗口。

编辑:哦,这是我现在的code无效。

1 个答案:

答案 0 :(得分:0)

想出来。经过一些调试后,我意识到问题是options.duration。不确定它究竟是什么,但它运作不正常。基本上我用一个静态值替换了选项[foo],并为每一个尝试了它,唯一一次失败的是如果我使用了options.duration而不是静态值。问题是每次持续时间乘以1000会使得运行速度太慢而无法看到任何东西。同样,我不知道为什么,但重点是......我修复了它。 Code。我必须做的就是修复过长的持续时间,删除* 1000并清除代码中的其他值。

Canvas.objects.Base.prototype.animate = function(options) {
  options.easing = Canvas.animation.easing[options.easing] || options.easing;
  options.duration = Canvas.animation.durations[options.duration] || options.duration;
  var start = Date.now(),
    total = start + options.duration,
    old = {},
    id,
    self = this;
  for (var i in options.properties) {
    if (options.properties.hasOwnProperty(i)) {
      old[i] = this[i];
    }
  }
  if (options.loop) {
    var animate = function() {
      for (var j in options.properties) {
        self[j] = old[j];
      }
      console.log(options.duration);
      self.animate({
        properties: options.properties,
        easing: options.easing,
        duration: options.duration,
        callback: animate
      });
    };
    options.callback = animate;
  }
  (function update() {
    var now = Date.now(),
      progress = Math.min((options.duration - (total - now)) / options.duration, 1);
    for (var i in options.properties) {
      if (options.properties.hasOwnProperty(i)) {
        self[i] = options.easing(now - start, old[i], options.properties[i] - old[i], options.duration);
      }
    }
    if (progress < 1) {
      id = requestAnimationFrame(update);
    } else {
      id = cancelAnimationFrame(id);
      if (options.callback) {
        options.callback();
      }
    }
  }());
};