Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting font-weight on Canvas text

I'm trying to write text over an image using the Canvas Element.

I've set the font-weight to 900, but on mobile it doesn't show up.

On desktop it's fine and even testing it within responsive mode it looks fine, but when I make it live, the heavier font-weight doesn't come through on my phone.

I tried the code snippet in the comments of Debug JS modifying some specific canvas element to debug it and I found that for some reason the ctx.font was only storing the font size and font name, but not the font weight.

I added the word bold and it would store that, but not bolder or a number value.

Does anyone have any idea what is going on here?

I've included a code snippet and a screenshot from my debugging that shows how it's storing the font value.

Screenshot

function main() {
  // Put template on canvas
  ctx.drawImage(img, 0, 0, size, size);

  ctx.font = "bold 110px 'Saira Condensed', sans-serif";
  ctx.textAlign = "center";
  ctx.fillStyle = "#ffffff";
  ctx.fillText(number, 325, 290);
}
like image 444
foodles Avatar asked Oct 29 '25 09:10

foodles


2 Answers

Chrome and Safari require that the font-style is also set in order to use a numerical value for font-weight:

const canvas = document.querySelector( "canvas" );
const ctx = canvas.getContext( "2d" );
// add 'normal' font-style
ctx.font = "normal 900 24px Unknown, sans-serif";
ctx.fillText( "bold", 50, 50 );

ctx.font = "24px Unknown, sans-serif";
ctx.fillText( "normal", 150, 50 );
canvas { background: white }
<canvas></canvas>
like image 169
Kaiido Avatar answered Oct 31 '25 23:10

Kaiido


When I tried this on Chrome (109.0.5414.87), numbered font-weights are converted to keywords. 100 to 600 are converted to "normal" and disappeared, and 700 - 900 are converted to "bold".

var context = document.createElement("canvas").getContext("2d");
context.font = "100 16px Arial" 
console.log(context.font) // prints "16px Arial"


context.font = "700 16px Arial" 
console.log(context.font) // prints "bold 16px Arial"
like image 34
Jenny C Avatar answered Oct 31 '25 22:10

Jenny C