Почему мои изображения не появляются на холсте? - PullRequest
0 голосов
/ 15 февраля 2019

Я хочу нарисовать много кругов разных размеров с одинаковым изображением на них, используя прототип.Проблема в том, что круги не появляются с изображениями, нарисованными на них.

Круги все еще там, потому что они видны, когда используется обводка, но изображения не прорисованы.Мне удалось нарисовать дугу с изображением без прототипа, но как только я ее использую, она не работает.

В консоли не появляются ошибки, поэтому неясно,мне то, что мне не хватает.Я пытался переместить слушателя событий за пределы прототипа, но изображения кругов по-прежнему не появлялись.

Если у кого-то есть понимание и, возможно, решение относительно того, почему это не работает, которым они могут поделиться, это будет очень цениться.

Вот код:

const ctx = document.getElementById('canvas').getContext('2d');
class Balls {
  constructor(xPos, yPos, radius){
    this.xPos = xPos;
    this.yPos = yPos;
    this.radius = radius;
  }
}
Balls.prototype.render  = function(){
  const img = document.createElement('img');
  img.src = 'crystal.jpg';
  ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI*2)
  ctx.stroke();	
  ctx.clip();
  img.addEventListener('onload', function(e){
    ctx.drawImage(img, this.xPos - this.radius, this.yPos - this.radius, 
    this.radius*2, this.radius*2);
  });
};
let object = new Balls(100, 100, 50);
object.render();
<canvas id='canvas'></canvas>

Ответы [ 3 ]

0 голосов
/ 16 февраля 2019

Вот, пожалуйста, я только что изменил 2 вещи, чтобы ваш код работал.

  1. load используется вместо Eventlistener вместо onload.
  2. useФункция стрелки для того, чтобы полагаться на родительский контекст вместо динамического контекста (this).

const ctx = document.getElementById('canvas').getContext('2d');
class Balls {
  constructor(xPos, yPos, radius) {
    this.xPos = xPos;
    this.yPos = yPos;
    this.radius = radius;
  }
}
Balls.prototype.render = function() {
  const img = document.createElement('img');
  img.src = 'https://via.placeholder.com/150.png?text=vijay'
  ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2)
  ctx.stroke();
  ctx.clip();
  img.addEventListener('load', (e) => {
    ctx.drawImage(img, this.xPos - this.radius, this.yPos - this.radius,
      this.radius * 2, this.radius * 2);
  });
};
let object = new Balls(100, 100, 50);
object.render();
<canvas id='canvas'></canvas>
0 голосов
/ 16 февраля 2019

Это альтернативный способ загрузки изображений, который является более модульным. Если вы создаете игру, вам пригодится класс Img.

Off-topic - if you want to load multiple images then you can add a totalLoaded counter to keep track of how many images has been loaded and if the totalLoaded count is equal to totalImages count then you can call a callback which will fire the animationLoop and preloads all the images.

const ctx = document.getElementById('canvas').getContext('2d');

// Img class to provide modular code
class Img {
  constructor(src, x, y, size) {
    this.x = x;
    this.y = y;
    this.size = size;
    this.src = src;
    this.img = new Image();
    this.img.src = this.src;
    this.isLoaded = false;
    this.img.addEventListener('load', (e) => {
      this.isLoaded = true;
      this.draw();
    });
  }

  draw() {
    if (this.isLoaded) {
      ctx.drawImage(this.img, this.x, this.y, this.size, this.size);
    }
  }
}

class Balls {
  constructor(xPos, yPos, radius) {
    this.xPos = xPos;
    this.yPos = yPos;
    this.radius = radius;
  }
}
Balls.prototype.render = function() {
  let imgx = this.xPos - this.radius;
  let imgy = this.yPos - this.radius;
  let imgr = this.radius * 2;
  let url = 'https://via.placeholder.com/150.png?text=Better';
  const img = new Img(url, imgx, imgy, imgr);
  ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2)
  ctx.stroke();
  ctx.clip();
  img.draw();
};
let object = new Balls(100, 100, 50);
object.render();
<canvas id='canvas'></canvas>
0 голосов
/ 16 февраля 2019

У вас было две проблемы в вашем коде.Во-первых, событие onload должно быть load.Во-вторых, this неизвестно внутри функции прослушивателя событий, поэтому this.radius и т. Д. Все не определены, а ctx.drawImage(img, this.xPos - this.radius, this.yPos - this.radius, this.radius*2, this.radius*2) не работает.

Я использовал некоторые переменные для this.xPos, this.yPos, this.radius, который можно использовать внутри функции обратного вызова слушателя событий.Надеюсь, это поможет!

const ctx = document.getElementById('canvas').getContext('2d');
class Balls {
  constructor(xPos, yPos, radius) {
    this.xPos = xPos;
    this.yPos = yPos;
    this.radius = radius;
  }
}
Balls.prototype.render = function() {
  const img = new Image();
  img.src = 'https://source.unsplash.com/random';
  var xPos = this.xPos, yPos = this.yPos, radius = this.radius
  ctx.arc(xPos, yPos, radius, 0, Math.PI * 2)
  ctx.stroke();
  ctx.clip();
  img.addEventListener('load', function(e) {
    console.log("load")
    ctx.drawImage(img, xPos - radius, yPos - radius, 
    radius*2, radius*2);
  });
};
let object = new Balls(100, 100, 50);
object.render();
<canvas id='canvas'></canvas>
...