This is a tutorial on rotating the canvas to produce text in directions other than horizontal. I wrote this because I wanted to write vertical text on a canvas and didn’t know how.
The Trick
You can only write text horizontally on a canvas. But we can rotate a canvas that we write on – then draw our horizontal text on the rotated canvas. When we’re finished we restore the canvas (restore it to its original orientation).
This can be a bit hard to imagine at first so I’ll work through a practical example. It is actually pretty easy once you know the trick.
Tutorial
Skeleton and Blank Canvas
Let’s start with a blank canvas with a border so we can see how big the canvas is.
<html>
<head>
<script src="example.js"></script>
</head>
<body onload="init();">
<canvas id="demoCanvas" width="400" height="240">
Please enable JavaScript
</canvas>
</body>
</html>
"use strict";
function init() {
var canvas = document.getElementById( "demoCanvas" );
var context = canvas.getContext( '2d' );
// draw a box around the canvas
context.beginPath(); // always start a new line with beginPath
context.lineWidth = 3;
context.moveTo( 0, 0 ); // start position
context.lineTo( canvas.width - 1, 0 );
context.lineTo( canvas.width - 1, canvas.height - 1 );
context.lineTo( 0, canvas.height - 1 );
context.lineTo( 0, 0 );
context.stroke(); // actually draw the line
}
This results in the blank canvas image:
Blank Canvas
Drawing Vertical Text Going Down
If we want to write text going down beginning at the upper left corner (co-ordinate [0,0]) then we have to virtually rotate the paper we are drawing on by holding onto the left-hand corner and rotating it 90 degrees (that’s pi divided by 2 radians) anti-clockwise.
So if we start with the following canvas – and we grab the origin (0, 0) with our finger and thumb:
Grab the original canvas at the top left hand corner
… then rotate the canvas 90 degrees anti-clockwise at this point:
Rotate the image at the origin 90 degrees
… and once rotated draw on the rotated canvas horizontally at (0, 0). Note that text is always drawn above the selected point.
Draw at the origin horizontally on the rotated canvas
When you restore the canvas to the original orientation using the restore() function the text will appear to go down from the top-left hand corner.
So let’s add the following code to our JavaScript init() function:
// start by saving the current context (current orientation, origin)
context.save();
// when we rotate we will be pinching the
// top-left hand corner with our thumb and finger
context.translate( 0, 0 );
// now rotate the canvas anti-clockwise by 90 degrees
// holding onto the translate point
context.rotate( Math.PI / 2 );
// specify the font and colour of the text
context.font = "16px serif";
context.fillStyle = "#ff0000"; // red
// set alignment of text at writing point (left-align)
context.textAlign = "left";
// write the text
context.fillText( "left-aligned 90 deg", 0, 0 );
// now restore the canvas flipping it back to its original orientation
context.restore();
This produces the following on the canvas:
Canvas with vertical text down from top-left corner
Drawing Vertical Text Going Up and Right-Aligned
What about text going up that lines up against the top-right?
This time we’ll grab the top-right hand corner of the canvas and rotate it -90 degrees (or 270 degrees) anti-clockwise.
Rotate the canvas holding the top-right hand corner
Bear in mind that any drawing done is relative from the translate point which in this case is top-right of the original canvas (or bottom-right of the rotated canvas). So when we draw text we’ll again draw to (0, 0) but right-align it so that the text extends to the left of the bottom-right corner of the rotated canvas.
Draw right-aligned text at the origin of the translated canvas
Now for some code:
// save orientation again
context.save();
// hold top-right hand corner when rotating
context.translate( canvas.width - 1, 0 );
// rotate 270 degrees
context.rotate( 3 * Math.PI / 2 );
context.font = "16px serif";
context.fillStyle = "#0000ff"; // blue
context.textAlign = "right";
// draw relative to translate point
context.fillText( "right-aligned 270 deg", 0, 0 );
context.restore();
Now we have a canvas that looks like the following:
Canvas with text going up aligned to the top right
Text 45 Degrees Down and Centred
So you should have a pretty good handle on this now. Let’s have some fun with 45 degree text sloping downwards but at the centre.
We’ll obviously rotate the canvas from the centre.
Rotate 45 degrees anti-clockwise from the centre
Then we can draw at the translate point but with centred text:
Draw text at translate point but centre-aligned
The code to do this:
context.save();
context.translate( canvas.width / 2, canvas.height / 2 );
context.rotate( Math.PI / 4 );
context.font = "16px serif";
context.fillStyle = "#00df00"; // green
context.textAlign = "center";
context.fillText( "center-aligned 45 deg", 0, 0 );
context.restore();
The canvas now looks like the following:
Canvas with 45-degree centred text
Very well explained
Wonderful explanation about the Translate method, I thought!
Very beautifully explained! Thanks!
Like the previous three guys said, very well explained (and it works first try).