Reputation: 35
why this doesnt work?
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function(){
ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
but this does?
var img = new Image();
img.onload = function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
how to make that ctx variable global so i could use in all functions? btw in all the tutorials everyone is using first method...
Got it working!
Upvotes: 4
Views: 206
Reputation: 1074028
I suspect the reason is timing: If your code is in a script
element above where your element with the id
"canvas"
is defined, your first code block won't find it in the document.getElementById("canvas")
call because it doesn't exist yet. By waiting for the image to load, you check for it later, when it exists.
If I'm correct, the solution is to move the script
block to the end of your body
element, just before your closing </body>
tag (or anywhere after the canvas
tag, really).
E.g., instead of:
<!-- ... -->
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function(){
ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
</script>
<!-- ... -->
<canvas id="canvas"></canvas>
<!-- ... -->
</body>
do this:
<!-- ... -->
<canvas id="canvas"></canvas>
<!-- ... -->
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function(){
ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
</script>
</body>
Putting your scripts at the bottom of the file is a good idea anyway, more: YUI Best Practices for Speeding Up your Website
Upvotes: 5
Reputation: 7408
Because html isn't loaded yet and #canvas element doesn't exist.
you can try this:
var canvas, ctx;
var img = new Image();
img.onload = function(){
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
Upvotes: 1
Reputation: 10251
My best guess is "threading" (or eventing).
When you call getContext
, it initializes a new Graphics Context, and it wants its results before your browser tries to redraw your screen. Normally, the first method should not be that much of a problem, as long as it runs synchronously (blocking, in other words: it returns immediately). But as soon as your browser needs to do some things asynchronously, it's "tired of waiting" for your context, and it begins to redraw your screen without waiting for the results, therefore invalidating your context. Then, you'll need to initialize a new context in order to draw things to your canvas.
This obviously depends on the browsers' implementation, and my guess is only based on what happens in graphics environments elsewhere (such as CoreGraphics, OpenGL, etc.). Graphics run on a single thread and that thread does not simply wait to catch up with your other threads. Even though Javascript abstracts a lot of this, you need to keep this in mind when building an graphics application.
Upvotes: 0