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!
-
ctx is declared in your main function?steo– steo2013年05月05日 11:03:36 +00:00Commented May 5, 2013 at 11:03
-
Is this all your code?Alexandre Khoury– Alexandre Khoury2013年05月05日 11:03:56 +00:00Commented May 5, 2013 at 11:03
-
no its not all code ctx is declared at start of the fileuser2351722– user23517222013年05月05日 11:05:54 +00:00Commented May 5, 2013 at 11:05
-
This question is similar to: Why does jQuery or a DOM method such as getElementById not find the element?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem.dumbass– dumbass2024年10月10日 19:29:49 +00:00Commented Oct 10, 2024 at 19:29
3 Answers 3
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
2 Comments
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';
Comments
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.