【问题标题】:How do I know when HTML5 Canvas' Rendering is Finished? [duplicate]我如何知道 HTML5 Canvas 的渲染何时完成? [复制]
【发布时间】:2016-12-27 14:13:48
【问题描述】:

html:

<canvas id="cnv" width="786" height="1113">

js:

var img = new Image(),
    cnv = document.getElementById('cnv');

var context = cnv.getContext('2d');

img.onload = function () {

    context.drawImage(img, 0, 0, 786, 1113);
    alert('finished drawing');

}

img.src = 'https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/logo_white_fe6da1ec.png';

http://jsfiddle.net/FxrSa/14/

我想在画布完成渲染后显示警报。但是在绘制图像之前会显示警报。

如何等待 GUI 线程完成他的渲染?

【问题讨论】:

  • 使用超时setTimeout(function() { alert('finished drawing'); }, 200);

标签: javascript html canvas html5-canvas


【解决方案1】:

画布drawImage 是同步的。甚至,really synchronous

您的问题是 alert() 正在阻塞,甚至是真正阻塞。

我的意思是它不仅会阻止 js 执行,还会阻止页面渲染。所以浏览器已经在你的画布上绘制了你的图像,但是当你调用alert()时还没有显示它。

人们应该始终避免使用alert,并将其替换为普通的 DOM 元素。

Ps:Here is a proof你的图片确实已经画在画布上了。

【讨论】:

  • 如果真的是同步的,是不是应该完全渲染后再返回?
  • 不,渲染在应该触发之前被警报阻止
  • 我明白了。但是如果实现的完美,那不就是drawImage-> render Canvas -> await Browser rendering -> await OS rendering return return return
  • 不!如何在同一帧上进行多个 drawImage + 图像处理???
  • so.. DOM 渲染和 js 是两个不同的线程,但只有一个可以运行,是吗?
【解决方案2】:

双缓冲画布

屏幕画布有两个像素缓冲区。一种叫做后台缓冲区,所有的渲染都是直接在后台缓冲区完成的。当您进行渲染调用时,ctx.drawImage(foo,0,0); 函数在绘制后台缓冲区像素之前不会返回。即使 GPU 正在渲染而 CPU 什么都不做,Javascript 也会等到渲染完成后再继续下一行。

当画布在屏幕上时,在当前执行完成之前,您不会看到任何渲染的结果。

function myRender(){
    ctx.draw(foo,0,0); // draw stuff  

    ... new pixel content is only in back buffer
    return;
}
function myLoop(){
    ctx.clearRect(,0,0,w,h);
    myRender();  // draw stuff
   .. new pixels not visible
}

myLoop(); 
// no more code

myLoop 函数返回并且javascript 无事可做时,DOM 会看到画布后缓冲区已更改。然后它将后缓冲区移动到前缓冲区,以便创建显示信号的硬件可以看到它。

这称为双缓冲,当您在屏幕上绘制并且屏幕在完成之前显示部分渲染时,它会阻止诸如剪切和闪烁等伪影。

当画布离屏时,没有前端缓冲区。

对于所有 DOM 内容也是如此。

【讨论】:

    【解决方案3】:

    作为一种解决方法,您可以尝试以下方法:

    //after the rendering
    setTimeout(function(){
     alert("Yay");
     },100);
    

    HTML5 Canvas: Get Event when drawing is finished

    【讨论】:

    • 不是真正的错误。
    • @Kaiido:规范说它是同步的。代码说它不是 -> 错误
    • 不,您没有正确阅读代码,只需检查 imageData,您会发现它是同步的。不是页面渲染(CSS + 媒体 + ...)
    • 信不信由你,这个答案基本上是正确的。但是,在我添加了新答案的链接问题中,有一种更准确的方法可以使时间发生。
    猜你喜欢
    • 2015-03-11
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    相关资源
    最近更新 更多