newspaint

Documenting Problems That Were Difficult To Find The Answer To

Writing Rotated Text on a JavaScript Canvas

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

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

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

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

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

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

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

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

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

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

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

Canvas with 45-degree centred text

4 responses to “Writing Rotated Text on a JavaScript Canvas

  1. Ron Hood 2014-11-15 at 12:07:43

    Very well explained

  2. Benjamin J. DeLong 2015-02-15 at 10:35:31

    Wonderful explanation about the Translate method, I thought!

  3. Rahul Sharma 2015-12-26 at 05:33:22

    Very beautifully explained! Thanks!

  4. Kirk Wayne 2017-09-21 at 18:55:55

    Like the previous three guys said, very well explained (and it works first try).

Leave a comment