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:

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:

… then rotate the canvas 90 degrees anti-clockwise at this point:

… and once rotated draw on the rotated canvas horizontally at (0, 0). Note that text is always drawn above the selected point.

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:

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.

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.

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:

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.

Then we can draw at the translate point but with centred text:

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: