blerontin
blerontin

Reputation: 3148

How can I specify font features when drawing to a HTML canvas?

The font I am using on my HTML page supports tabular figures, which is great for presenting rows of currency numbers nicely. They can be activated in CSS by using either:

.table {
  font-variant-numeric: tabular-nums;
}

or the more low-level way with:

.table {
  font-feature-settings: "tnum" on;
}

But how do I activate tabular figures when drawing on a JavaScript Canvas object using the CanvasRenderingContext2D.fillText() method? I tried putting the font-feature-settings line within the @font-face CSS block that defines the font to be loaded, but that did only affect the rendering within HTML, not the Canvas drawing.

Upvotes: 2

Views: 647

Answers (2)

blerontin
blerontin

Reputation: 3148

A workaround that can be used in case the font has a monospaced alternative available is to define a separate font-face using the monospace variant that only covers number characters, and use the normal font as a fallback. That way the browser will render all numbers with equal width but use the (possibly more nice) default font for punctuation or currency symbols without the need to switch manually in between characters.

CSS:

@font-face {
  font-family: "SomeDefault";
  /* ... points to regular font variant ... */
}

@font-face {
  font-family: "SomeNumbers";
  /* ... points to monospaced font variant ... */
  unicode-range: U+0030-0039;
}

JavaScript:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

/* TODO: Make sure the fonts are already loaded, either by referencing them in HTML or by using the FontFace API */
ctx.font = '20px SomeNumbers, SomeDefault, sans-serif';
ctx.fillStyle = '#444';
ctx.fillText('Text with numbers: 1.234$', 10, 40);

Upvotes: 1

Thomas
Thomas

Reputation: 182093

I think it's just not supported, but would gladly be proven wrong.

As a workaround, you could use measureText() to find the width of the widest digit, and render the digits individually one by one, using the widest digit's width as a step size.

Or, if your design allows, you could choose a different font whose figures all have the same width to begin with. This is a fairly common default.

Upvotes: 2

Related Questions