最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to determine when a canvas has finished loading - Stack Overflow

programmeradmin3浏览0评论

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
 |  Show 2 more ments

2 Answers 2

Reset to default 4

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

发布评论

评论列表(0)

  1. 暂无评论