【问题标题】:cancelAnimationFrame inside of object method not working对象方法内部的cancelAnimationFrame不起作用
【发布时间】:2016-02-13 00:22:52
【问题描述】:

cancelAnimationFrame() 在对象的方法中调用时似乎不起作用。我尝试将this 值绑定到回调函数(as demonstrated on MDNsetTimeout),但是在使用cancelAnimationFrame() 时收到了TypeError。然后我尝试将this 值设置为名为@9​​87654327@ 的局部变量并再次调用cancelAnimationFrame()。那个时候,我没有收到错误,但动画本身仍在播放。如何取消动画?

我在下面重现了我遇到的问题。如果你打开一个控制台窗口,你会看到动画还在运行。

function WhyWontItCancel() {
  this.canvas = document.createElement("canvas");
  this.canvas.width = 200;
  this.canvas.height = 10;
  document.body.appendChild(this.canvas);
  this.draw = this.canvas.getContext("2d");
  this.draw.fillStyle = "#f00";
  this.position = 0;
};

WhyWontItCancel.prototype.play = function() {
  if (this.position <= 190) {
    this.draw.clearRect(0, 0, 400, 10);
    this.draw.fillRect(this.position, 0, 10, 10);
    this.position += 2;
  } else {
    //window.cancelAnimationFrame(this.animation.bind(this));
    var _this = this;
    window.cancelAnimationFrame(_this.animation);
    console.log("still running");
  }

  this.animation = window.requestAnimationFrame(this.play.bind(this));
};

var animation = new WhyWontItCancel();
animation.play();

【问题讨论】:

    标签: javascript constructor bind requestanimationframe cancelanimationframe


    【解决方案1】:

    您似乎在这里错过了两件事。首先,this.animation = window.requestAnimationFrame(this.play.bind(this)); 行在调用play()总是 被调用。与您的想法相反,cancelAnimationFrame 仅删除了先前请求的 RAF 调用。严格来说,这里甚至没有必要。其次,您不必绑定每个 RAF 调用;你可能只做一次:

    function AnimatedCanvas() {
      this.canvas = document.createElement("canvas");
      this.canvas.width = 200;
      this.canvas.height = 10;
      document.body.appendChild(this.canvas);
      this.draw = this.canvas.getContext("2d");
      this.draw.fillStyle = "#f00";
      this.position = 0;
    
      this.play = this.play.bind(this); // takes `play` from prototype object
    };
    
    AnimatedCanvas.prototype.play = function() {
      if (this.position <= 190) {
        this.draw.clearRect(0, 0, 400, 10);
        this.draw.fillRect(this.position, 0, 10, 10);
        this.position += 2;
        this.animationId = window.requestAnimationFrame(this.play);
      }
    };
    

    您可能希望在原型中添加取消以停止动画,例如:

    AnimatedCanvas.prototype.cancel = function() {
      if (this.animationId) {
        window.cancelAnimationFrame(this.animationId);
      }
    };
    

    ...但关键是,它在问题中描述的用例中没有用。

    【讨论】:

      猜你喜欢
      • 2015-07-29
      • 2016-09-05
      • 2013-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多