在 class 中使用 requestAnimationFrame

Using requestAnimationFrame in a class

当我在 class.

中使用它时,

requestAnimationFrame 不是 return 常规 this

我一直在寻找关于这个主题的所有帖子(试图将 step() 函数作为匿名函数封装到 animate 中......),但我仍然有同样的问题。

class Sprite {

  constructor(canvas, imageSrc) {
    this.canvas = canvas;
    this.img = new Image();
    this.img.src = imageSrc;
    this.height = 18;
    this.width = 16;
    this.scale = 4;
    this.scaledWidth = this.scale * this.width;
    this.scaledHeight = this.scale * this.height;
    this.cycleLoop = [0];
    this.currentLoopIndex = 0;

    this.img.onload = () => {
      this.init();
    }
  }

  init() {
    this.ctx = this.canvas.getContext('2d');
    this.ctx.webkitImageSmoothingEnabled = false;
    this.ctx.mozImageSmoothingEnabled = false;
    this.ctx.imageSmoothingEnabled = false;
  }

  drawFrame(frameX, frameY, canvasX, canvasY) {
    this.ctx.drawImage(
      this.img,
      frameX * this.width,
      frameY * this.height,
      this.width,
      this.height,
      canvasX,
      canvasY,
      this.scaledWidth,
      this.scaledHeight
    );
  }

  animate() {
    requestAnimationFrame(this.step());
  }

  step() {
    console.log(this);
    console.log(this.ctx);
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

    this.drawFrame(this.cycleLoop[this.currentLoopIndex], 0, 0, 0);
    this.currentLoopIndex++;


    if (this.currentLoopIndex >= this.cycleLoop.length) {
      this.currentLoopIndex = 0;
    }
    requestAnimationFrame(this.step());
  }
}

step()中,第一个console.log(this)显示了一个具有ctx属性的Character对象。由于某些原因,第二个 console.log(this.ctx) 未定义。

所以我得到一个:

Uncaught TypeError: Cannot read property 'clearRect' of undefined
    at Character.step (sprite.js:49)
this.canvas = canvas;

在 Sprite 的构造函数中定义 class。

this.ctx = this.canvas.getContext('2d');

然而在图像的 onload 事件的回调函数中定义。所以我最好的猜测是当你在 Sprite 实例上调用 animate() 方法时,onload 事件没有触发,因此上下文没有定义。

似乎在定义 ctx 之前调用了 step()。很可能是因为 step() 在创建 ctximg.onload() 回调之前被调用。

确保在 init() 之后调用 step()

或在 constructor 中设置 ctx,使用:

this.ctx = canvas.getContext('2d');