This wide- and large- screen layout may not work quite right without Javascript.

Maybe enable Javascript, then try again.

Home Fiddling with PCs

Canvas:
Text Centering

The HTML/HTML5 canvas will easily draw text centered. The canvas can automatically center text horizontally or vertically or both. There's no need to measure the text. For centering text on a canvas, obtaining text metrics then feeding them into a relatively complex calculation is not necessary.

(Although not important to centering text, you should more generally understand how canvases use two different coordinate systems simultaneously.)

The HTML/CSS convention that center means only horizontally while middle means only vertically has been extended to the canvas too. (This possibly unique convention goes all the way back to the early HTML table cells.)

(top)

Horizontal Centering

Here's an example of text centered horizontally on a canvas, and the code that produced the example. The displayed lines show the baseline and centerpoint. The text is displayed centered horizontally on the point marked by the crosshairs. In this case, the line has been calculated to be the horizontal center of the box.

The baseline has been allowed to default to alphabetic, which is usually appropriate. For English, the alphabetic baseline is the bottom of the capital letters; descenders hang below this line.

(Both canvas coordinates and CSS coordinates are zero-based, so for example the columns for a 100 pixel wide canvas are actually numbered from 0 through 99. For simplicity and focus on the concept of two simultaneous coordinate systems, the examples below just cheerfully ignore this fact. Please overlook as unimportant the many "off by one" errors that result.)

Text is drawn on a canvas exactly the same way as it would be if it were not centered. Just one additional line of code is needed to center it. That one additional line is highlighted in this example.

auto-centering horizontally

HTML:

<canvas id="cvs" width="300" height="50"><p>canvas unsupported</p></canvas>

CSS:

/* none */

Javascript:

var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
ctx.font = 'normal bold 20px sans-serif';
ctx.textAlign = 'center';


ctx.fillText("Kilroy was here", 150, 40);
// in this example 150 is the center of the box that's 300 wide
// in this example 40 is near the bottom of the box that's 50 deep

(top)

Text Size

It's possible to specify canvas text size in any of the units common in CSS (px, pt, ex, em, mm, %, etc.). However canvas text size is usually specified in pixels (px). The size in pixels is the total height of the text from the tops of capital letters to the bottoms of the descenders. In other words for English it includes everything except leading.

Having the text size specified in the same units used for sizing the canvas (pixels/px) makes it pretty easy to be sure there's enough space on the canvas for displaying the text without any overlaps. Knowing the text size in pixels should keep calculations simple. Specifying text size in pixels/px also makes all text appear the same size regardless of font (which is not always true if the text size is specified in points/pt instead).

(top)

Vertical Centering

Here's a very similar example, except the text is centered vertically rather than horizontally. The line of code that does this is highlighted.

auto-centering vertically

HTML:

<canvas id="cvs" width="300" height="50"><p>canvas unsupported</p></canvas>
<!-- (same) -->

CSS:

/* none */

Javascript:

var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
ctx.font = 'normal bold 20px sans-serif';
ctx.textBaseline = 'middle';


ctx.fillText("Kilroy was here", 20, 25);
// in this example 20 is near the left edge of the box that's 300 wide
// in this example 25 is the middle of the box that's 50 deep

Using the lines as a visual guide, the text may at first appear to have been positioned a little too high. That's because the canvas's vertical centering algorithm uses the full height of the text (in this example the specified 20 pixels), including possible descenders. To see that the text really is centered vertically, look at the bottom of the 'y' as well as the top of the 'K'.

(top)

Centering Both Horizontally And Vertically

Centering both ways is simply a matter of combining the methods for centering vertically and centering horizontally. Here's an example. As always, the crosshairs mark the point specified to the fillText(...) command.

auto-centering both directions

HTML:

<canvas id="cvs" width="300" height="50"><p>canvas unsupported</p></canvas>

CSS:

/* none */

Javascript:

var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
ctx.font = 'normal bold 20px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';


ctx.fillText("Kilroy was here", 150, 25);
// in this example 150 is the center of the box that's 300 wide
// in this example 25 is the middle of the box that's 50 deep

(top)

What If The Text Is Too Large?

Canvas text handling seems to be intended for labelling but not a lot more. It does not handle multi-line text easily (it does not do word wrap at all). So what exactly happens if the text is too large? In that case the text is displayed as specified anyway, but is simply clipped at the edges of the canvas. So for example horizontally centered text will probably be cut off on both sides.

Here's an example:

auto-centering attempt when text too long

HTML:

<!-- same -->

CSS:

/* none */

Javascript:

var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
ctx.font = 'normal bold 20px sans-serif';
ctx.textAlign = 'center';

ctx.fillText("Kilroy was not close to here", 150, 40);

// in this example 150 is the center of the box that's 300 wide
// in this example 40 is near the bottom of the box that's 50 deep

(top)

Why Does It Sometimes Seem To Stop Working?

A common recommendation for entirely clearing a canvas is to simply write a value to one of the canvas's dimensions, like this:
canvas.width = canvas.width;
This is only one very simple line of Javascript source code, and in this sense it is indeed quite short.

However this method is rather obscure and hard for a maintainer to understand. And, even though it's only one line of Javascript source, it may cause lots of behind-the-scenes work for the Javascript engine. So overall it often performs worse than plainly coding what you really mean:
ctx.clearRect(0,0, canvas.width,canvas.height);
Most importantly, it does more than just visually clear the canvas. Writing a value to one of the canvas's dimensions completely resets all of the canvas's contexts, including any settings of context.textAlign or context.textBaseline you had made.

Now that you understand what's going on, this coding is easily avoided. No longer will your canvases ever suddenly stop centering text.

(top)









Location: (N) 42.67995, (W) -70.83761
 (North America> USA> Massachusetts> Boston Metro North> Ipswich)

Email comments to Chuck Kollars
Time: UTC-5 (USA Eastern Time Zone)
 (UTC-4 summertime --"daylight saving time")

Chuck Kollars headshot Chuck Kollars' other web presences include Chuck's books and Chuck's movies.

You may also wish to look at Dad's photo album.

All content on this Personal Website (including text, photographs, audio files, and any other original works), unless otherwise noted on individual webpages, are available to anyone for re-use (reproduction, modification, derivation, distribution, etc.) for any non-commercial purpose under a Creative Commons License.