HTML5 Canvas Images Are Not Loading Using DrawImage()
Solution 1:
Your problem has to do with the scope - which refers to the accessibility of variables, objects and functions - and the meaning of the this keyword depending on the actual scope.
To get a better understanding let's have a look at the following example:
class Game {
constructor() {
console.log("Game constructor:", this);
this.player = new Image();
this.player.onload = this.draw;
this.player.src = "https://picsum.photos/200/300";
}
draw() {
console.log("draw:", this);
}
}
let game = new Game();
If you click 'Run code snippet', you should see the following output in the console:
Game constructor: {}
draw: <img src="https://picsum.photos/200/300"></img>
As you can see a call to this inside draw()
does not refer to the same thing anymore. In the first case it's an object instance of Game (hinted by the curly brackets) and in the second case it's an instance of a HTMLImageElement.
So your code simply fails because:
this.loadedSprites += 1;
if (this.loadedSprites >= this.sprites) {
don't reference the Game class's private variables loadedSprites
and sprites
- in fact it doesn't refer anything at all as it's simply undefined within the scope of the draw function thus loadedSprites
doesn't ever get incremented.
One workaround is passing the context of the Game class to each Image instance using a new property e.g. .reference
.
this.player = new Image();
this.player.reference = this;
this.player.onload = this.draw;
and use it inside draw() like:
draw() {
this.reference.loadedSprites += 1;
}
Here's a complete example based on your code:
const canvas = document.querySelector("#canvas");
class Game {
constructor(c) {
this.c = c; //canvas
this.ctx = c.getContext("2d"); // context
this.sprites = 5;
this.loadedSprites = 0;
this.player = new Image(); // define images
this.player.reference = this;
this.bg = new Image();
this.bg.reference = this;
this.fg = new Image();
this.fg.reference = this;
this.north = new Image();
this.north.reference = this;
this.south = new Image();
this.south.reference = this;
this.pX = 10; // player starting location
this.pY = 150;
// set sprite locations and load.
this.player.onload = this.draw;
this.player.src = "https://picsum.photos/id/237/20/20";
this.bg.onload = this.draw;
this.bg.src = "https://picsum.photos/id/22/20/20";
this.fg.onload = this.draw;
this.fg.src = "https://picsum.photos/id/30/20/20";
this.gap = 80;
this.constant = this.north.height + this.gap;
this.north.onload = this.draw;
this.north.src = "https://picsum.photos/id/37/20/20";
this.south.onload = this.draw;
this.south.src = "https://picsum.photos/id/137/20/20";
}
//draw images
draw() {
let ref = this.reference;
ref.loadedSprites += 1;
if (ref.loadedSprites >= ref.sprites) {
ref.ctx.drawImage(ref.bg, 0, 0);
ref.ctx.drawImage(ref.north, 100, 0);
ref.ctx.drawImage(ref.south, 0, 0 + ref.constant);
ref.ctx.drawImage(ref.fg, 0, ref.c.height - ref.fg.height);
ref.ctx.drawImage(ref.player, ref.pX, ref.pY);
}
}
}
let game = new Game(canvas);
<canvas id="canvas" width="512" height="512">
</canvas>
Post a Comment for "HTML5 Canvas Images Are Not Loading Using DrawImage()"