Should I register a callback to handle the canvas blob object or does the CanvasRenderingContext2D.drawImage() blocking javascript execution until drawImage() is completed?
-
Yes it runs synchronously, but it's unclear what you are talking about with "blob object" – Kaiido Jun 25 '18 at 12:05
-
After drawImage() execution I want to call **canvas.toBlob()** method and I'd like to be sure that the new image is drawn successfully. @Kaiido https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob – dmraptis Jun 25 '18 at 12:34
1 Answers
Yes CanvasRenderingContext2D.drawImage does run synchronously, but maybe not in the way you want...
If the sourceImage provided has not finished to fetch its resource (in case of HTMLImageElement or SVGImageElement) then, it will not wait for this.
var img = new Image();
img.src = "https://slowserv.er/bigImage.png";
ctx.drawImage(img, x, y); // here it won't wait for the image to be fetched
But if the image has been completely fetched, and its metadata has been parsed but the image data has not yet been decoded, then drawImage
will wait for it to be decoded. You can see a demo of this by running this Answer from Firefox.
This behavior seems to be catch-able only in Firefox, since Chrome will actually wait for the image to be decoded before firing the onload event.
So to answer your question, if the sourceImage is in a loaded status (e.g img.naturalWidth !== 0
for <img>
), then yes, you can be sure that drawImage will get executed before the next line of code is.
if(img.naturalWidth !==0) { // here we are sure our image is loaded
ctx.drawImage(img, x, y); // and here we are sure it has been drawn on the canvas
// even though toBlob is itself async
// this will pick the canvas has it is now
ctx.canvas.toBlob(onblobgenerated, options);
}

- 123,334
- 13
- 219
- 285
-
Thank you @Kaiido for your valuable advice! My canvas image source is a HTMLVideoElement connected to a MediaStream (web camera), so I should be sure that the image is loaded before calling getImage – dmraptis Jun 25 '18 at 13:16
-
Yes, same as with an HTMLImageElement.naturalWidth, you can check HTMLVideoElement.videoWidth to be sure it has something to be drawn. Or even simply `video.onloadedmetadata` or `oncanplay` if it has its autoplay set to true, or even `video.play().then(drawAndExport)` since I guess you are targeting new browsers. – Kaiido Jun 25 '18 at 13:20
-
I'll go with video.play().then(drawAndExport) Promise API solution, thanks again! – dmraptis Jun 25 '18 at 13:50