- From: Simon Sarris <simon.sarris@gmail.com>
- Date: Fri, 20 Sep 2013 14:16:30 -0400
- To: WHATWG List <whatwg@whatwg.org>
Summary: You can draw zero-sized Images and objects with zero-sized source rects to the canvas context. You cannot draw zero-sized Canvases, you get an InvalidStateError. According to the spec this is right, but I think there should be more consistency in handling these cases. drawImage can be called with an Image, a Canvas, or a Video element, so you typically see calls like: ctx.drawImage(imageReference, 0, 0); ctx.drawImage(canvasReference, 0, 0); 99% of the time you can think of them as interchangeable. Let's talk about our 1%ers. I came across an interesting (and none-too-useful, but we can blame the browser for that) error when drawing a canvas with zero width and height: inMemoryCanvas.width = 0; // Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable. ctx.drawImage(inMemoryCanvas, 0, 0); According to the specification, this is the right error to throw: > If the image argument is an HTMLCanvasElement object with either a horizontal dimension or a vertical dimension equal to zero, then throw an InvalidStateError exception, return aborted, and abort these steps. The bothersome thing is that: 1. Zero-sized Images do not have any such error 2. calling drawImage with a source rectangle, using context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh), when the source rectangle has zero width or height, does not give an error. Per the spec: > If one of the sw or sh arguments is zero, abort these steps. Nothing is painted. So zero-sized sources are fine if they are an HTMLImageElement or a source rectangle, but not fine if they are HTMLCanvasElement. This seems inconsistent, and the error given seems odd too. It's not very descriptive and not immediately clear what is wrong. This issue came to my attention because a friend asked for help, who was drawing randomly-sized canvases onto a main context. He suspected InvalidStateError was some bizarre closure bug where part of the canvas state was being lost, but of course the truth was more mundane - some but not all zero-sized objects cannot be drawn to the canvas context. Anywho, I recommend either considering all zero-sized sources as invalid, and perhaps giving a more descriptive error, or simply allowing a zero-sized canvas to be a valid drawImage argument so that it may run its natural course (draw nothing), just like Image and zero-sized source rect arguments. Simon Sarris ~~~ For reference, below is a simple example showing both a zero-sized img being drawn and a zero-sized canvas: // this <img>'s width/height/naturalWidth/naturalHeight are all zero: var img = document.createElement('img'); // Totally fine, no error: ctx.drawImage(img, 0, 0); var inMemoryCanvas = document.createElement('canvas'); inMemoryCanvas.width = 0; inMemoryCanvas.height = 0; // Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable. ctx.drawImage(inMemoryCanvas, 0, 0);
Received on Friday, 20 September 2013 18:16:55 UTC