Home > Enterprise >  HTML Canvas 2DContext.font - Font's size has no effect - Google Font "Exo 2" might be
HTML Canvas 2DContext.font - Font's size has no effect - Google Font "Exo 2" might be

Time:12-05

I am creating a canvas & filling it up with text. It works perfectly with different fonts EXCEPT for Exo 2.

Exo 2 is a Google font, and I suspect that maybe the trailing "2" is causing an issue while parsing the font string.

The font loads fine and actually renders to the canvas, but the font size never changes. I've tried loading the variable font as well as loading multiple weights.

This works fine:

//omitted some ctx boilerplate
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')

ctx.font = `100px Arial`

Here's where things break down:

ctx.font = `100px Exo 2` // I could set this to 1000000px, and it doesn't change.

Is it possible that the font's name is throwing off the font string?

CodePudding user response:

I found my issue! I was using Next.js's @next/font/google to load/optimize the font. The font's name was subsequently changed to '__Exo_2_0987d5','__Exo_2_Fallback_0987d5' instead of just Exo 2. Instead of referring to the font's official name, I refer to the generated name from the code:

export const exo2 = Exo_2({
  weight: 'variable',
  subsets: ["latin"] 
})
ctx.font = `100px ${exo2.style.fontFamily}` 

The canvas rendering works great now. This is one of the strangest problems I have ever created for myself.

CodePudding user response:

When a font name has a single word starting by a digit, the font name must be quoted.

So set your font property to

ctx.font = `100px "Exo 2"`;

document.fonts.load('30px "Exo 2"').then(() => {
  const canvas = document.querySelector("canvas");
  const ctx = canvas.getContext("2d");
  ctx.save();
  ctx.font = `30px Exo 2`;
  //                   ^  An unquoted single word starting by a digit is invalid
  ctx.fillStyle = "red";
  ctx.fillText("Without quotes", 30, 30);
  ctx.restore();
  ctx.font = `30px "Exo 2"`;
  //               ^_____^ These make the difference
  ctx.fillStyle = "green";
  ctx.fillText("With quotes", 30, 80);  
});
@font-face {
  font-family: 'Exo 2';
  font-style: normal;
  font-weight: 400;
  src: url('https://cdn.jsdelivr.net/npm/@openfonts/[email protected]/files/exo-2-latin-400.woff2');
}
<canvas></canvas>

  • Related