javascript - 对象方法内的 cancelAnimationFrame 不起作用

标签 javascript constructor bind requestanimationframe cancelanimationframe

cancelAnimationFrame() 在对象的方法内部调用时似乎不起作用。我已尝试将 this 值绑定(bind)到回调函数(as demonstrated on MDNsetTimeout),但在使用 cancelAnimationFrame() 时收到 TypeError。然后,我尝试将 this 值设置为名为 _this 的局部变量,并再次调用 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();

最佳答案

似乎您在这里错过了两件事。首先,this.animation = window.requestAnimationFrame(this.play.bind(this)); 行在 play() 时被调用叫。与您的想法相反,cancelAnimationFrame 仅删除先前请求的 RAF 调用。严格来说,这里甚至没有必要。其次,您不必绑定(bind)每个 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);
  }
};

您可能希望将取消添加到您的原型(prototype)中以便能够停止您的动画,例如:

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

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

关于javascript - 对象方法内的 cancelAnimationFrame 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35367149/

相关文章:

javascript - 何时在 Angularjs 中使用过滤器与指令

javascript - Spring MVC 与 Mustache 发送字符串变量。

node.js - 如何在一个 Node 服务器中绑定(bind) http 和 https

c++ - Boost::bind 和 std::copy

javascript - AWS Cognito - 使用 IAM 角色访问 S3

javascript - 如何在javascript中动态添加对象到对象中?

constructor - Kotlin 在声明之前初始化变量?

java - 构造函数是否必须使用传递给它的所有参数?

c++11 - 关于在 C++11 中初始化向量

c++ - 我可以使用 std::bind 将指向成员函数的指针转换为指向函数的指针吗?