Использование requestAnimationFrame в классе - PullRequest
0 голосов
/ 22 июня 2019

requestAnimationFrame не возвращает обычный 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) показывает объект Character с атрибутами ctx. Второй console.log(this.ctx) по некоторым причинам не определен.

Итак, я получаю:

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

Ответы [ 2 ]

2 голосов
/ 22 июня 2019
this.canvas = canvas;

определяется внутри конструктора вашего класса Sprite.

this.ctx = this.canvas.getContext('2d');
Однако

определено внутри функции обратного вызова для события onload . Поэтому мое лучшее предположение - когда вы вызываете метод animate () в экземпляре Sprite, событие onload еще не сработало, поэтому контекст не определен.

1 голос
/ 22 июня 2019

Похоже, step() вызывается до определения ctx.Скорее всего, потому что step() вызывается до обратного вызова img.onload(), который создает ctx.

Обязательно позвоните step() после init().

Или настройте ctx в constructor, с помощью:

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