la guarida de DuckMaestro

Using DirectX-like coordinates with the HTML5 Canvas

Suppose you have a bit a graphics programming background, and want to quickly jump in on this HTML5 canvas action. The first thing you'll notice is that draw calls with the canvas by default are in logical coordinates. It is the typical logical coordinate system where the top-left (x,y) is (0,0), positive x is in the rightward direction, and positive y is in the downward direction. However in DirectX (and perhaps OpenGL as well) draw calls happen using projection space where (0,0) represents the center of the screen, x=-1 is the left edge of the buffer, x=+1 is the right edge, y=-1 is the bottom, and y=+1 is the top (DirectX - 3D Spaces).

After deciding I didn't want to start my transform stack in logical space, I decided I'd quickly calculate the transform needed to base everything around the projection space-style units. One of the nice things about HTML5 is that it's fairly simple to manage your transformation stack, as it's built into the graphics context itself. So to achieve my goal, all I need to do is call setTransform() on the canvas context as one of the first actions in my draw loop. This call resets the transformation stack and inserts the provided coefficients with the first transform in the fresh stack (HTML5 Draft - Canvas Transformations).

As it turns out, the 3x3 homogeneous matrix we're looking for is:

+w / 2    +0        +w / 2
+0        -h / 2    +h / 2
+0        +0        +1

To set this up with your HTML5 canvas, assuming you already have your context created, just call:

context.setTransform(
    context.canvas.width / 2.0, 
    0, 
    0, 
    -context.canvas.height / 2.0, 
    context.canvas.width / 2.0, 
    context.canvas.height / 2.0
);

Done! Now by default your drawing calls will be in the domain of [-1,+1] for x and y, and where +y points in the up direction.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License except where otherwise noted.


comments powered by Disqus