It contains just a bidimensional matrix of points.
This little guide introduces you to use effectively this API to write shapes and control them with the mouse.
In this simple example we are going to draw some rectangular shapes.
Save the shapes to draw
The first thing to do is to save the shapes inside an array:var objs = [ {name:'shape2', color:'green', x:30, y:50, angle:Math.PI/2, width: 40, height: 50 }, {name:'shape1', color:'red', x:40, y:30, angle:Math.PI/4, width: 30, height: 40 } ];Objects inside the array will be drawn one after the another with the first object in the background and the last object in foreground.
var i, obj; ctx.clearRect(0, 0, canvas.width, canvas.height); //empty the canvas for (i = 0;i < objs.length;i++){ obj = objs[i]; ctx.save(); // save context ctx.translate(obj.x, obj.y); // apply transformations (I'll explain later) ctx.rotate(obj.angle); ctx.fillStyle = obj.color; // draw ctx.fillRect( -(obj.width / 2), -(obj.height / 2), obj.width, obj.height ); ctx.restore(); // restore the context saved }The canvas coordinates start with 0,0 on the upper left corner. but you usually don't need to calculate the position of each shape. The canvas API gives the power to move the axis instead, and then draw the shapes around the point 0,0.
Introducing transformations
Transformations moves X and Y axis in the space. In the bidimensional world there are 3 main type of transformations:- translation
- skew
- scale
They are usually represented with a matrix
x a1,b1,c1
y a2,b2,c2
1 0,0,1
that express these three equations
x' = a1x + b1y + c1
y' = a2x + b2y + c2
1 = 0x + 0y + 1
These equations transform the original (x, y) coordinates in a new pair of coordinates (x', y').
In bidimensional transformations the last equation is an identity (It is alway true).
If you pay enough attention you will notice that you can define a matrix that doesn't change the original coordinates. This is called the identity matrix:
x 1,0,0
y 0,1,0
1 0,0,1
x' = 1x + 0y + 0 = x
y' = 0x + 1y + 0 = y
1 = 0x + 0y + 1
Now starting with the identity matrix I'll try to explain transformations (I am not a mathematician so forgive me if the explanation is not formally correct or inaccurate).
t1 and t2 are translations (in the x and y axis respectively). They move the axis left/right and up/down.
A translation of 0 means no translation.
In fact:
x 1,0,t1
y 0,1,t2
1 0,0,1
x' = 1x + 0y + t1 = x + t1
y' = 0x + 1y + t2 = y + t2
1 = 0x + 0y + 1
s1 and s2 means scale. s1 scales the x axis while s2 scales the y axis. A multiplication of 1 means no scale.
x s1,0,0
y 0,s2,0
1 0,0,1
x' = s1x + 0y + 0 = s1*x
y' = 0x + s2y + 0 = s2*y
1 = 0x + 0y + 1
sk2 and sk1 skew respectively the x and y axis
x 1,sk1,0
y sk2,1,0
1 0,0,1
x' = 1x + sk1y + 0 = x + sk1*y
y' = sk2x + 1y + 0 = y + sk2*x
1 = 0x + 0y + 1
Now the question is: and the rotation ?
The rotation is a combination of two transformations: skew and scale.
The formula is
x cos(angle),-sin(angle),0
y sin(angle),cos(angle),0
1 0,0,1
x = x * cos(angle) + y * -sin(angle)
y = x * sin(angle) + y * cos(angle)
The order in which you apply the tranformation is very important:
In fact if we first rotate and then translate we are translating the axis using the new rotated axis.
As a rule of thumb, we usually need to:
- translate
- rotate
- scale
Back to canvas
Canvas has a complete API for transformations.
You can get more information on MDN.
In the previous example we applied translate and rotate tranformations.
These functions change the state of our drawing context. And affects all drawing operations so, in order to apply different transformations on each shape, we need to reset the drawing context every time.
Otherwise the next transformation would be applied over the previous.
Next part I'll show how to interact with objects.