简体   繁体   中英

How do I know when HTML5 Canvas' Rendering is Finished?

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/

I want to show the alert after the canvas finished his rendering. But the alert show before the image is drawn.

How can I wait for the GUI thread to finish his rendering?

Canvas drawImage is synchronous. And even, really synchronous .

Your problem is that alert() is blocking, and even really blocking.

By this I mean it does not only block the js execution, it also blocks the page rendering. So the browser has painted your image on your canvas, but didn't display it yet when you called alert() .

One should always avoid alert and replace it with normal DOM elements.

Ps: Here is a proof that your image is indeed already painted on the canvas.

Double buffered canvas

An on screen canvas has two pixel buffers. One is called the back buffer, all rendering is done directly to the back buffer. When you make a render call, ctx.drawImage(foo,0,0); the function will not return until it has drawn the back buffer pixels. Even if the GPU is doing the rendering and the CPU is doing nothing, Javascript will wait until the rendering is complete befor moving on to the next line.

When the canvas is on the screen, you will not see the results of any rendering until the current execution has finished.

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

When the myLoop function has returned and javascript has nothing to do, the DOM will see that the canvas backbuffer has changed. It then moves the back buffer to the front buffer so that it can be seen by the hardware that creates the display signal.

This is called double buffering, and it stop artifacts like shearing and flickering caused when you draw to the screen and the screen displays part of the rendering before it is finished.

When the canvas is offscreen, there is no front buffer.

The same is true for all DOM content.

As a workaround you may try this:

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

HTML5 Canvas: Get Event when drawing is finished

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM