The variable does not work inside the function

why doesn't it 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 does it?

 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 this ctx variable global so that I can use it in all functions? By the way, in all textbooks everyone uses the first method ...

It worked!

+4
source share
3 answers

I suspect the reason is synchronization: if your code is in the script element above where your element with the id "canvas" defined, your first block of code will not find it in the call to document.getElementById("canvas") because it is not yet exist. While waiting for the image to load, you check it later when it exists.

If I'm right, the solution is to move the script block to the end of your body element just before your closing </body> (or somewhere after the canvas tag, really).

For example, 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 the following:

 <!-- ... --> <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> 

Inserting your scripts at the bottom of the file is anyway a good idea anymore: YUI Best Practices to speed up your site

+5
source

Since html is not yet loaded, and the #canvas element does not exist.

you can try the following:

 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'; 
+1
source

My best guess is threading (or eventing).

When you call getContext , it initializes a new graphics context and wants to get its results before your browser tries to redraw your screen. Usually the first method should not be such a big problem if it works synchronously (blocking, in other words: it returns immediately). But as soon as your browser needs to do some things asynchronously, it is "tired of waiting" for your context and begins to redraw your screen without waiting for results, therefore it will invalidate your context. Then you will need to initialize a new context in order to draw things on your canvas.

This obviously depends on the implementation of browsers, and my hunch is based only on what happens in graphical environments elsewhere (such as CoreGraphics, OpenGL, etc.). Graphics runs on a single thread, and this thread is not just waiting to catch up with your other threads. Although Javascript abstracts a lot, you should keep this in mind when creating a graphical application.

0
source

Source: https://habr.com/ru/post/1479230/


All Articles