So I was making a rather large canvas that was filled with 1x1 pixels, and I wanted to make a loading screen for it. The problem after the loop filling the canvas finishes, it alerts that it has finished loading, but the canvas has not actually changed. I made a jsfiddle here to demonstrate. How do I actually find out when the canvas has actually loaded using javascript or Jquery, and what is causing this behavior?
var ctx=document.getElementById('canvas').getContext('2d');
for(var x=1;x<600;x++){
for(var y=1;y<600;y++){
var color= '#' + Math.floor (Math.random() * 16777215).toString(16);
ctx.fillStyle=color;
ctx.fillRect(x,y,1,1);
}
}
alert('done!');
So I was making a rather large canvas that was filled with 1x1 pixels, and I wanted to make a loading screen for it. The problem after the loop filling the canvas finishes, it alerts that it has finished loading, but the canvas has not actually changed. I made a jsfiddle here to demonstrate. How do I actually find out when the canvas has actually loaded using javascript or Jquery, and what is causing this behavior?
var ctx=document.getElementById('canvas').getContext('2d');
for(var x=1;x<600;x++){
for(var y=1;y<600;y++){
var color= '#' + Math.floor (Math.random() * 16777215).toString(16);
ctx.fillStyle=color;
ctx.fillRect(x,y,1,1);
}
}
alert('done!');
Share
Improve this question
asked May 5, 2013 at 12:58
scrblnrd3scrblnrd3
7,4249 gold badges36 silver badges65 bronze badges
7
-
I don't know about you, but the alert does fire after you filled noise in the canvas. Works fine. It could be the browser, where it fires the alert before it renders the canvas, since
alert
does block the UI. – Joseph Commented May 5, 2013 at 13:03 - @JosephtheDreamer It certainly doesn't for me. Not sure why it does that. – scrblnrd3 Commented May 5, 2013 at 13:04
- @scrblnrd3 browser, version and OS? – Joseph Commented May 5, 2013 at 13:04
- Chrome on Mac OSX Mountain lion – scrblnrd3 Commented May 5, 2013 at 13:04
- @scrblnrd3 I have Chrome 26 on Windows. Can you check on other browsers? – Joseph Commented May 5, 2013 at 13:09
2 Answers
Reset to default 4Since you said jquery was ok, just fire a custom event when the loops are done looping.
Any code that needs the canvas fully loaded can go in the event handler.
// Listen for custom CanvasOnLoad event
$(document).on( "CanvasOnLoad", canvasOnLoadHandler );
var ctx=document.getElementById('canvas').getContext('2d');
for(var x=1;x<600;x++){
for(var y=1;y<600;y++){
var color= '#' + Math.floor (Math.random() * 16777215).toString(16);
ctx.fillStyle=color;
ctx.fillRect(x,y,1,1);
}
// fire CanvasOnLoad when the looping is done
if(x>=599){
$.event.trigger({
type: "CanvasOnLoad"
});
}
}
console.log("...follows the for loops.");
// handle CanvasOnLoad knowing your canvas has fully drawn
function canvasOnLoadHandler(){
console.log("canvas is loaded");
}
It is just like a load-progress animation. Updating/advancing that animation from a running function usually doesn't work right away (screen updates when that function finishes).
Your canvas-code is (automatically) wrapped in a onload
function: window.onload=function(){ /*your code here*/ };
.
The last line of that function is alert('done!');
, so naturally you'll get the alertbox before the screen updates and you see the noize.
One solution is to first one set and display's a loading-image, then using a setTimeOut
(say 30ms) one renders the canvas, ending that canvas-function with another setTimeOut to remove the loading-image again.
Note: as you probably know, your code will generate (a lot of) hex-colors like #3df5
and #5d8a6
, both of which aren't valid colors! Also you used 16777215, but Math.random() needs to be multiplied by 16777216. To fix this, you might want to try:
color='#'+((Math.random()+1)*16777216|0).toString(16).substr(1);
Here is some good read about random colors.
See this JSFiddle result as an example.
Hope this helps.