4

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!

asked May 5, 2013 at 11:00
4
  • ctx is declared in your main function? Commented May 5, 2013 at 11:03
  • Is this all your code? Commented May 5, 2013 at 11:03
  • no its not all code ctx is declared at start of the file Commented 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. Commented Oct 10, 2024 at 19:29

3 Answers 3

5

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

answered May 5, 2013 at 11:06
Sign up to request clarification or add additional context in comments.

2 Comments

yes thank you! got it from your first answer but thanks for explaining more
@user2351722: Good deal, glad that helped!
1

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';
answered May 5, 2013 at 11:08

Comments

0

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.

answered May 5, 2013 at 11:07

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.