2013-05-05 29 views
3

因此,我製作了一個填充1x1像素的相當大的畫布,並且我想爲它製作加載畫面。循環填充畫布後的問題結束後,它警告已完成加載,但畫布實際上並未改變。我在這裏做了一個jsfiddle來演示。我怎樣才能真正發現canvas何時使用javascript或Jquery實際加載,以及導致此行爲的原因是什麼?如何確定畫布何時完成加載

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!'); 
+0

我不瞭解你,但是在畫布上填滿了噪音後,警報響起。工作正常。它可能是瀏覽器,它在呈現畫布之前會觸發警報,因爲'alert'確實會阻止用戶界面。 – Joseph 2013-05-05 13:03:28

+0

@JosephtheDreamer它當然不適合我。不知道它爲什麼這樣做。 – scrblnrd3 2013-05-05 13:04:13

+0

@ scrblnrd3瀏覽器,版本和操作系統? – Joseph 2013-05-05 13:04:34

回答

4

既然你說jquery是好的,只需在循環完成循環時激發自定義事件。

需要畫布完全加載的任何代碼都可以放入事件處理函數中。

// 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"); 
} 
2

它就像加載進度動畫一樣。從正在運行的函數更新/推進該動畫通常不會馬上工作(該函數完成時的屏幕更新)。

將您的畫布編碼(自動)封裝在onload函數中:window.onload=function(){ /*your code here*/ };
該函數的最後一行是alert('done!');,所以自然你會在屏幕更新之前得到alertbox,並且你看到noize。

一種解決方案是首先設置一個並顯示加載圖像,然後使用setTimeOut(比如說30ms)渲染畫布,並以另一個setTimeOut結束該畫布函數以再次刪除加載圖像。

注意:正如您可能知道的那樣,您的代碼將生成(很多)十六進制顏色,如#3df5#5d8a6,這兩種顏色都不是有效的顏色!此外,您使用16777215,但Math.random()需要乘以16777216.要解決此問題,您可能需要嘗試:
color='#'+((Math.random()+1)*16777216|0).toString(16).substr(1);
Here是關於隨機顏色的一些很好的閱讀。

查看本文以JSFiddle result爲例。

希望這會有所幫助。

+0

我沒有看到你關於變量「顏色」的觀點。我看起來很好。無論如何,變量聲明被提升到函數的開頭,移動它不會改變任何內容。 – 2013-05-05 13:18:38

+0

@dystroy:我相應地更新了我的答案。但是,*在我看來* jslint/crockford是正確的:不應該重新聲明變量。 – GitaarLAB 2013-05-05 13:54:54

+0

該變量實際上只聲明一次。移動var聲明並不是壞習慣。 – 2013-05-05 13:57:09

相關問題