user2351722
user2351722

Reputation: 35

variable not working inside function

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

Answers (3)

T.J. Crowder
T.J. Crowder

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

Louay Alakkad
Louay Alakkad

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

cutsoy
cutsoy

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

Related Questions