[whatwg] Canvas in Workers
Ian Hickson
ian at hixie.ch
Mon Nov 19 10:04:27 PST 2012
On Mon, 19 Nov 2012, Gregg Tavares (社ç~T¨) wrote:
>
> Sorry if this is clear in the specs but can you explain how sizing the
> canvas works?
There's two sizes involved in a canvas: the size of the bitmap, and the
size of the rendering. Both default to 300x150 in the absence of explicit
sizing.
The size of the bitmap, for getContext()-based canvases, is given by the
<canvas> element's width and height attributes. For rendering contexts
created by their constructor, it's initially set by the arguments to the
constructor. It can be changed using the width and height attributes on
the rendering context. When a context is bound to a canvas, it takes on
the dimensions of the canvas bitmap. To change the canvas bitmap
dimensions before calling setContext() or transferControlToProxy(), you
use the width and height attributes as before. Once you've called
setContext() or transferControlToProxy(), though, to avoid race conditions
with workers, only the width and height attributes on the rendering
context affect the canvas, so you have to first bind the rendering context
and then set the size if you need the size changed.
The size of the rendering is set by CSS, and defaults to whatever the
width and height attributes of the canvas element are. Note that if you
are drawing to the canvas from a worker and you have changed the
dimensions of the bitmap after you called setContext() or
transferControlToProxy(), you will have to explicitly set the dimensions
of the canvas using the element's attributes or CSS, otherwise the canvas
bitmap will be resized for rendering.
> // main.html
> <canvas></canvas>
Here the bitmap and rendering are 300x150.
> <script>
> var canvas = document.getElementsByTagName('canvas')[0];
> var worker = new Worker('clock.js');
> var proxy = canvas.transferControlToProxy());
At this point, canvas.width/.height no longer affect the bitmap size.
> worker.postMessage(proxy, [proxy]);
>
> setTimeout(function() {
> canvas.width = 200; // does this work? What happens?
This just changes the rendered width.
> }, 4000);
> </script>
>
> // clock.js worker
> onmessage = function (event) {
> var context = new CanvasRenderingContext2d();
The constructor could be called with arguments, as in new
CanvasRenderingContext2d(200, 150);
That size will have no effect though, since the context is immediately
bound to a canvas bitmap and takes the bitmap's size:
> event.data.setContext(context);
> setInterval(function () {
> context.width = 400; // Can I do this? What happens when I do?
This changes the canvas bitmap's dimensions (and resets all state of the
rendering context). It doesn't change the canvas element's rendered
dimensions, however (we could push the state out like the bitmap itself, I
guess, but that would make the DOM change out of the blue which is weird).
> context.clearRect(0, 0, context.width, context.height);
> context.fillText(0, 100, new Date());
> context.commit();
> }, 1000);
> };
HTH,
--
Ian Hickson U+1047E )\._.,--....,'``. fL
http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,.
Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
More information about the whatwg
mailing list