An example of the transform and setTransform functions
Posted on 2nd February 2013Summary
An example of and guide to the transform function (and also the setTransform() function)
- Introduction
- Browser support
- An example
- The transform() vs setTransform() functions
- An ellipse example
- Using translate() for antialiasing
- Other transformation functions
Introduction
The setTransform() and transform() functions use "matrix" calculations to transform the canvas. What does this mean? In practice it's a combination of the scale() and translate() functions and also allows the skewing of the canvas. So if you don't need skewing then you can quite realistically get by with the scale() and translate() functions. A transform looks like this:
context.setTransform(scaleX, skewX, skewY, scaleY, translateX, translateY);
And these arguments are:
- scaleX: Increases or decreases the size of the pixels in the X direction
- skewX: This effectively angles the X axis up or down
- skewY: This effectively angles the Y axis left or right
- scaleY: Increases or decreases the size of the pixels in the Y direction
- translateX: Moves the whole coordinate system in the X direction (so [0,0] is moved left or right)
- translateY: Moves the whole coordinate system in the Y direction (so [0,0] is moved up or down)
The difference between the two functions is that the transform() function adds to whatever transformations that you've done before. So this:
context.transform(1,0,0,1,10,10); context.transform(1,0,0,1,10,10); context.transform(1,0,0,1,10,10);
Is the same as doing this:
context.setTransform(1,0,0,1,30,30);
And if you do another setTransform(1,0,0,1,30,30) call - it remains the same.
Browser support
All browsers suppport the transform and setTransform functions - though in the example below not all browsers support the HTML5 range input (the slider) - so you may see text inputs instead.
An example
This example allows you to see the effect of each type of transformation. Keep in mind that the order of the arguments is not immediatly obvious - so the appropriate code is shown below the chart.
Scale X: | |
Scale Y: | |
Skew X: | |
Skew Y: | |
Translate X: | |
Translate Y: |
The transform() vs setTransform() functions
At first the two functions may seem similar. However when you start to do multiple transformations the difference may become apparent. The transform() function ADDS the transformation that you give it to whatever the current transform is. Whereas the setTransform() SETS it to whatever you give it.
context.transform(1,0,0,1,5,5); // A translate by [5,5] context.transform(1,0,0,1,5,5); // A translate by [5,5] context.transform(1,0,0,1,5,5); // A translate by [5,5] context.transform(1,0,0,1,5,5); // A translate by [5,5]
Has the same result as this:
context.setTransform(1,0,0,1,20,20); // A translate by [20,20]
An ellipse example
Like the example shows, the scale part of the transformation (or the stand-alone scale function) can be used like the example below to scale the canvas in the appropriate direction so that a standard circle becomes an ellipse.
<script>
context = document.getElementById("cvs").getContext('2d');
context.transform(1.5,0,0,1,0,0);
context.beginPath();
context.fillStyle = 'red';
context.lineWidth = 4;
context.arc(75,50,35,0,2 * Math.PI, true);
context.stroke();
context.fill();
</script>
Using translate() for antialiasing
By default canvas will have blurry lines if you use whole pixels (no decimals) for coordinates such as: context.fillRect(50,50,10,10); You can avoid this though if you simply translate the canvas by half a pixel before-hand and then always use whole numbers to draw with: context.translate(0.5, 0.5) Keep in mind though that if you clear the canvas by setting the width to itself - this also removes any translation or other transform that you may have performed - so you will need to do the antialiasing fix again.
Other transformation functions
There other transformation functions that aren't covered by the transform function such as:
- rotate(): This rotates the canvas around [0,0] - the top left corner (unless you have translated). Be aware that the angle you give should measured in RADIANS and NOT degrees. 1 radian = 180 / Math.PI (which is roughly 57.296 degrees).
- clip(): This reduces the drawing area to whatever the current path is. Anything else is not painted to the canvas. There's another article on the clip() function here: http://www.rgraph.net/blog/an-example-of-the-html5-canvas-clip-function.html
- translate(): The translate function is available for just "moving the coordinate system" of the canvas.
- scale(): The scale function is available if you only want to increase or decrease the size of everything on the canvas. You could use this to make your own zoom effect for example.