Reputation: 33
EDIT : I just found something that works on every page load except the first (hard) load. It's a 'weird tip to get it to work' because it does not use onload. E.g.
This works on loads 2...n:
case String:
var img = new Image();
img.onload = function() {
//context.drawImage(img,0,0);
};
img.src = detail;
context.drawImage(img,0,0);
This does not work on any load 1...n:
case String:
var img = new Image();
img.onload = function() {
context.drawImage(img,0,0);
};
img.src = detail;
//context.drawImage(img,0,0);
I am not very happy that I miss the most important load (the first one), but at least there is some progress.
Can someone guide me to explain what is going on here? I'm really baffled. I want image to load and draw to canvas every time. Is this an unrealistic expectation?
I'm using FF 7.0.1 on Ubuntu, my user agent is : Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
EDIT : Still fail after all approaches tried in comments. I will keep thinking about it. I think it has something to do with the canvas no longer being accessible (even though the variable resolves correctly and no error is thrown in JS Debugger under FF).
I am writing a js framework for rendering to canvas to provide an easy API to write GUI with less code and prettier code than using Canvas API. It's just a wrapper around canvas. But I am not a js expert even though I love js, now anyway.
The following code in the closure can execute and access the scope of the img variable, can raise an alert form that scope on image load, can change the img css style properties, but will not execute a drawImage on the canvas context in context variable.
Before the closure context.fillRect will work fine, but inside the closure it does not. I think there is something fundamental I have not learned yet, since I have coded similar onload with closure looking code before and everything just worked. Hopefully today is the day I learn something new.
RenderProvider.prototype.drawImage = function(srcElement,context,state,detail) {
if(detail == undefined || detail == null) {
alert("Image is not present. Ignoring.");
return;
}
switch(detail.constructor) {
case String:
alert("Image is from String");
var img = new Image();
img.src = detail;//'t.jpg';//'Star-Field.gif';//http://www.google.com/favicon.ico';
img.onload = function (e) {
alert('Drawing ' + img + ' to ' + context);
alert('Context dim ' + context.canvas.width + ',' + context.canvas.height );
context.drawImage(img,20,20);
return true;
};
img.src = detail;//'t.jpg';//'Star-Field.gif';//'http://www.google.com/favicon.ico';
break;
Upvotes: 3
Views: 281
Reputation: 3808
You need to wait for the window.onload event as well as the image onload event, as Phil H is suggesting. Are you doing that? I tested your first sample up there but waited for window.onload and it works on the first load. The second one does not work. I am not sure why.
Upvotes: 0
Reputation: 20131
Where is this function being defined? If you are defining this function in code in script tags, then the canvas element (and context) won't exist when the code is parsed, and cannot be passed in.
Note also that the closure will not be executed until after the block enclosing it has been run.
Upvotes: 1
Reputation: 5326
I made a jsfiddle that works if you want to play with it.
var img = new Image();
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
img.src = 'http://www.google.com/favicon.ico';
img.onload = function() {
context.drawImage(this, 20, 20);
}
Note that I use this
instead of img
inside the callback function. img
works too, but it's more usual to use this
. Also, you can but the img.src = ...
after the callback function definition and it still works.
Upvotes: 1