Question

I'm using canvas for a game. I have a Sprite object which draws itself to the canvas, in the Sprite class I create the Image member along with it's src attribute when i create the object.

Here's the code that's not working:

Sprite.prototype.draw = function(Context){
    this.Image.onLoad = function(){
    Context.drawImage(this.getImage(),this.getX(),this.getY());
    };
};

In the objects constructor i pass in a string param which is the file path to the Image - this is being stored correctly.

I have a feeling the problem lies in a setImage function:

Sprite.prototype.setImage = function(){
    this.Image = document.createElement('img');
    this.Image.src = this.getImagePath(); //This just returns the path as a                                                                      
                                            string
};

I get no errors at runtime... yet the image is not drawn to the screen?

Anyone able to point out what's up? I've searched for answers to this but in everyone all the elements are created in the html document whereas all of mine are created on the fly, don't know if that makes any difference.

Cheers

Was it helpful?

Solution

You code is building on synchronous model but you are using asynchronous calls which means this will not work as you might expect.

You first set an url on your image object which means the process of loading is invoked immediately. At the time you then call draw the image may or may not be already loaded (if it exists in the cache this process is usually instant) so when you then set your onload handler (which must be lower case) the image object is perhaps pass that stage and it will never be called (the browser doesn't wait for it to be set).

For this to work you need to use a different model, for example callbacks and/or promises. For simplicity callbacks will do just fine.

An example of this could be:

Sprite.prototype.setImage = function(callback){
    this.Image = document.createElement('img');
    this.Image.onload = function() {
        callback(this); /// just for ex: passing image to callback (or other inf)
    }
    this.Image.src = this.getImagePath();
};
Sprite.prototype.draw = function(Context){
    Context.drawImage(this.getImage(), this.getX(), this.getY());
};

This way when an image has loaded it will call the function you specified as callback, again just for example:

var sprite = new Sprite(); /// pseudo as I don't know you real code

sprite.setImagePath('someurl');
sprite.setImage(imageLoaded);

function imageLoaded() {
    sprite.draw(context);
}

(Personally I would merge setImagePath and setImage - keep it simple.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top