2012-05-15 98 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