【问题标题】:JavaScript canvas live updateJavaScript 画布实时更新
【发布时间】:2017-03-24 12:20:30
【问题描述】:

我编写了一个分形图像生成器,它的运行时间从几分之一秒到几分钟不等,具体取决于每个像素的迭代次数。在当前版本中,用户必须等待图像完全渲染,直到他可以看到结果。在此期间,浏览器 UI 被阻止,Firefox 将每 10 秒显示一条警告消息,询问脚本是否应该继续、调试或停止。

问题:是否可以在脚本运行时显示画布内容的更新?

【问题讨论】:

  • 在递归调用分形生成函数时尝试使用 setTimeout 以避免 firefox 弹出警告消息

标签: javascript canvas live-update


【解决方案1】:

是的

在当前调用(通常由事件启动)返回之前,UI 会被阻止。当函数返回对 DOM 的任何更改时,将更新下一个事件(如果有的话)并被放置在调用堆栈上并调用,否则 javascript 引擎只是等待一个事件。

您可以使用 setTimeout 来安排一个事件,处理一些像素,设置超时再次退出等等。

仅在逻辑流程方面的示例

var complete = false;
var pixels = 100000;
var pixelsPerCall = 1000;
function addPixels(){
     // process x number of pixels
     var i = pixelsPerCall;
     while(i-- && pixels--){
         // do a pixel
     }
     if(pixels === 0){
          complete = true;
     }
     if(! complete){
         setTimeout(addPixels,0);
     }
}
addPixels();

虽然对于这种类型的应用程序,您最好使用 webWorkers。根据机器拥有的内核数量,您可以获得吞吐量的巨大增加。例如,具有 8 个内核的 I7 CPU 将完成工作的速度大约是 8 倍。此外,网络工作者不会阻塞 DOM,因此可以运行任意时间。

【讨论】:

  • 感谢您对正确方向的提示。我尝试了 window.setTimeout 和 window.requestAnimationFrame 以每秒更新一次图像。两者都在工作,但 requestAnimationFrame 确实每秒频繁更新画布,而 setTimeout 需要的时间在 ~0.5 到 ~2 秒之间变化。这2种方法的优缺点是什么?
  • 例如,向后兼容呢?每个现代浏览器都会支持 requestAnimationFrame 吗?
  • @stbi requestAnimationFrame (rAF) 让 DOM/浏览器知道调用的代码与图形相关。它保存在屏幕外缓冲区中所做的任何更改,直到显示刷新(垂直同步),这样您就不会在看不到图形时出现闪烁/剪切或浪费时间呈现图形。我通常总是运行 rAF 更新来处理所有与 DOM 相关的更新。如果无事可做,我只需请求下一帧并退出。还有很多其他原因。我不知道哪些浏览器不支持它
  • 经过一些测试后,我决定坚持使用 setTimeout,因为 requestAnimationFrame 使 Firefox 对用户输入(如按钮点击)没有响应(Chrome 和 Opera 在这里工作正常)。用户应该能够通过单击“停止”按钮来停止图像绘制过程。
【解决方案2】:

一种可能的方法是将计算拆分成块,使用setTimeout / setImmediate 运行每个步骤,更新画布并运行另一个块。

这不仅会逐步更新画布,还会阻止浏览器抱怨脚本运行时间过长。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多