2012-05-15 99 views
2

有什麼辦法強制畫布更新?我想顯示一條加載消息,但遊戲在顯示之前鎖定加載。我覺得我需要告訴畫布「現在畫」加載函數被調用之前,但也許是有另一種方式......強制畫布更新

編輯:

OK,只是要清楚,我已經寫一個非常小的骯髒的腳本(最好我可以在我的茶歇:P)來證明我正在努力過來。在這裏:

<html> 
<head> 
    <title>test page</title> 
</head> 

<body onload="init();"> 
    <canvas id="cnv" width="300" height="300"> 
     canvas not supported.<br/> 
    </canvas> 
</body> 
</html> 

<script type="text/javascript"> 

    var ctx; 

     function init() 
    { 
     var canvas = document.getElementById('cnv'); 
     ctx = canvas.getContext('2d'); 

     ctx.fillStyle = "rgb(255, 0, 0)"; 
     ctx.fillRect(0,0,300,300); 

     FakeLoad(); 

     ctx.fillStyle = "rgb(0, 255, 0)"; 
     ctx.fillRect(0,0,300,300); 
    } 

    function FakeLoad() 
    { 
     var d = new Date(); 
     var start = d.getTime(); 

     while (new Date().getTime() - start < 5000) 
     { 
      //emulate 5 secs of loading time 
     } 
    } 
</script> 

現在的想法是腳本應該畫一個紅色的正方形完成後,顯示其「加載」和綠化廣場。但是如果將其複製到html文件中,您將看到的所有內容都是5秒的暫停,然後綠色顯示,而不是紅色。在我的腦海中,我想要有一些像ctx.Refresh()這樣的命令;在我畫綠色方塊告訴它「現在更新!不要等待!」之後但從答覆來看,這不是解決問題的方法。

我該怎麼辦? :)

+0

和你的代碼?我們怎麼知道你甚至沒有一些示例代碼就可以畫出來。 – Joseph

+0

我已經編輯了一個示例腳本:) –

+1

可能重複[如何強制在畫布中更新顯示](http://stackoverflow.com/questions/4982631/how-to-force-a-display-畫布更新) –

回答

5

你可以做,使畫布上顯示你之前做的時間越長的任務一個短暫的停頓後開始FakeLoad另一件事:

var canvas = document.getElementById('cnv'); 
    ctx = canvas.getContext('2d'); 

    ctx.fillStyle = "rgb(255, 0, 0)"; 
    ctx.fillRect(0,0,300,300); 

    setTimeout(function() { 
     FakeLoad(); 

     ctx.fillStyle = "rgb(0, 255, 0)"; 
     ctx.fillRect(0,0,300,300); 
    }, 20); // 20 ms - should be enough to draw something simple 
+0

接受爲答案 - 簡單而有效,只是延遲一點點給帆布機會更新如此完美的單靜態加載屏幕 - 謝謝:) –

2

如果我正確地理解了你,沒有辦法更新畫布,就像你可以在WPF中重新渲染/繪製或重新流動HTML DOM一樣。

這是因爲畫布使用中間模式圖形。從本質上講,畫布保留知識的唯一方面是組成畫布的像素。當您調用繪製矩形或繪製線時,構成矩形或線條的像素將添加到畫布上,並且就畫布而言,它會忘記繪製矩形或繪製圓形調用的所有內容,因此我們無法刷新畫布並得到相同的結果。

如果您在尋找「保留」渲染到其中的圖形知識的東西,那麼您可以嘗試使用SVG,它使用保留模式圖形。基本上它有它自己的DOM(對象的循環(循環,矩形等)),每當一個區域被弄髒時它們都會被重新渲染。

總之,這個頁面是幫助您瞭解即時模式圖形和保留模式圖形之間的區別非常好:http://msdn.microsoft.com/en-us/library/ie/gg193983(v=vs.85).aspx

所有這一切說,如果我誤解你的問題,請接受我的道歉!

更新

從問題的額外信息,

你之所以從來沒有看到綠色的廣場,因爲主要的JavaScript線程總是忙你的五個第二個循環。它從來沒有時間更新UI。爲了讓畫布更新您的加載屏幕,您需要異步執行所有加載。

你會做什麼樣的加載?如果是圖片等,您可以使用$.ajaxjQuery來抓取它們。這將異步地從他們的位置獲取圖像,一旦檢索到最後一張圖像,您就可以清除並重新繪製您的內容。

我想是這樣的:

<script type="text/javascript"> 

    var ctx; 

    function init() 
    { 
     var canvas = document.getElementById('cnv'); 
     ctx = canvas.getContext('2d'); 

     ctx.fillStyle = "rgb(255, 0, 0)"; 
     ctx.fillRect(0,0,300,300); 

     FakeLoad(); 
    } 

    function FakeLoad() 
    { 
     $.ajax({ 
      url: "www.foo.com/bar.jpg", 
      success: function(data) 
      { 
       // Do something with the data (persist it) 
       RenderApp(); 
      } 
     }); 
    } 

    function RenderApp() 
    { 
     // Rendering the rest of the application/game 
     ctx.fillStyle = "rgb(0, 255, 0)"; 
     ctx.fillRect(0,0,300,300); 
    } 

</script> 

顯然,這是有點psudo碼,但希望它會給你一些想法!

讓我知道你是否需要任何澄清!

+0

不是我以前的樣子,但仍然非常有趣 - 感謝您的信息! –

+1

輝煌的答案,我從中學到了很多!在這種情況下,我已經選擇了下面的setTimeout()方法,因爲它是最簡單的加載類型(生成大量的程序數據,加載精靈,初始化數據庫等),但我也投了票,因爲我認爲它非常有用和有用。我真的愛你:) –

+0

不用擔心!感謝您的反饋! :) – Andy