+ 10
I am having some issues with ctx.drawImage().. I made an object called Bird with the method show.
This method is executing 60 times per second... There is no problem with the setInterval, just the method. this.show = function() { var avatar = new Image(); avatar.src = 'https://www.sololearn.com/images/fb-story-icon.jpg'; avatar.onload = function() { ctx.beginPath(); ctx.drawImage(avatar, this.x, this.y, this.r, this.r); } } I also have some functions that change x and y., so it looks like the image is moving around the canvas. When I write this.r, the image is not showing up. When I don't, it is stuck on the left top corner...
9 ответов
+ 1
Ok, like this one?
Click on the screen to jump
If that code not going to help you, well I will recommend to use 'console.log(var)'.
https://code.sololearn.com/Wc1lVhq7RPk8/?ref=app
+ 12
@Thomas Omg thank you!! So this is what was the problem. the line saying ctx.drawImage shouldve been outside the avatar.onload... It makes sense now. Thanks
+ 11
@Thomas I don't want that to happen. I want it to move and change its position
+ 9
@John I am going to provide with the full code so you can understand... X and y are already defined...
+ 9
I recommend playing it on the computer as I haven't done much for the mobile devices
+ 6
better give us some more code so we can play with it without completing all the missing parts....
+ 3
The problem with your code is because of scope. When using `this` it refers to the current scope. The code for drawing the image is inside the method `onload` of `avatar`, so `this` refers to `avatar`. So the arguments you provided for drawImage() refer to properties of the image. Unfortunately, the image has no such properties as x, y and r. That is why nothing is drawn. Something was drawn, however, when you removed `this.r` because drawImage() tries to convert `this.x` and `this.y` to numbers. Since they are undefined values, they are treated as 0s. When not specifying values for width and height, but destination position, that is its default behaviour. That's why the image gets drawn at the top left corner of the screen.
+ 1
If I set this code (Code below) outside of the avatar.onload function, the image goes down, nothing else.
I think if you set that code in onload function it will only run 1 time and the image will just stay there.
Code:
"ctx.drawImage(avatar, this.x, this.y, this.r, this.r);"
+ 1
@Thomas You definitely got the scope right, but your code did not show the bird image. If at all it does, you are creating a new image every time you call the show method in the draw function. Worse, the loop is running **at** 60fps, meaning there will be a lot of garbage. As an optimization:
this.isLoaded = false;
this.loadAvatar = function() {
// `this` in this function block refers to the bird.
this.avatar = new Image();
this.avatar.src = 'https://www.sololearn.com/Icons/Courses/0.png';
// If I write `this.isLoaded` in the onload method it refers to
// the avatar, but I want it to refer to the bird. So, I create a
// variable _this and store in it the value `this` which is the bird.
var _this = this;
this.avatar.onload = function() {
// `this` in this function block refers to the avatar.
//_this correctly maps to the bird now.
_this.isLoaded = true;
}
}
this.show = function() {
if (this.isLoaded) {
ctx.drawImage(this.x, this.y, this.r, this.r);
}
}
Call bird.loadAvatar() probably in the window.onload or when the document is ready.
EDIT: The bird shows in Thomas' code, probably because the image is cached. So the second you set the src, it is ready. However, writing #cleancode is the way to go. Keep in mind that the show() is called 60 times a second. This means that new variables and images are created a lot of times. And re-declaring variables is not good. There are times you can't just escape creating variables many times a second, but where there is, do it. Garbage collection can really slow down a game.