1

You can measure text to get the width of a sentence like this:

ctx.measureText('I am a sentence').width

You can do this because you set the font on the context directly to match whatever CSS-styled text in your HTML that you're trying to really measure.

ctx.font = '24px MyFont';

But what if I want to apply whitespace: pre to the text? I seem to be getting weird results that don't measure up.

What I'm trying to do is simply calculate the words that can fit safely on a single line. That's it. But sometimes what I measure is smaller than what gets rendered, so I am starting to suspect that the canvas measurement technique isn't actually an accurate tool.

How do I accurately measure the width of a sentence taking into account all the features of the styling such as letter-spacing, whitespace: pre, etc.?

Lance
  • 75,200
  • 93
  • 289
  • 503

1 Answers1

0

Use CSS and the Range API, which offers a getBoundingClientRect method, this is still the most powerful combination we have access to while waiting for the Font metrics API.

const target = document.getElementById( 'target' );
const range = document.createRange();
const bounds = document.getElementById( 'bounds' );
range.selectNode( target.firstChild );
onresize = e => {
  const rect = range.getBoundingClientRect();
  bounds.style.left = rect.x + 'px';
  bounds.style.top = rect.y + 'px';
  bounds.style.width = rect.width + 'px';
  bounds.style.height = rect.height + 'px';
};
onresize();
#bounds {
  position: absolute;
  border: 1px solid;
}
<pre id="target">
Draw some     rect

around  
      me
</pre>
<div id="bounds"></div>

You can see a more complete example of this combination in order to draw on a canvas, probably more like you need, on this related Q/A.

Kaiido
  • 123,334
  • 13
  • 219
  • 285