如何在内容渲染前获取文本宽度?canvas 的 measureText
了解一下。
前言
在我们开发过程中,有时候需要获取文本实际在页面中的内容宽度,通常的做法是,使用Element.getBoundingClientRect()
获取到的 width,即为当前元素在浏览器中展示的实际宽度。
该方法返回的 DOMRect
对象中的 width
和 height
属性是包含了 padding
和 border-width
的,而不仅仅是内容部分的宽度和高度。
如何在渲染前获取
getBoundingClientRect
或者其他一些从 Dom 元素上获取到宽度的方法有时候并不能满足我们的开发,有些时候,我们需要在内容渲染前就拿到宽度,该如何去做?
这个时候,我们可以使用 canvas
里的一个 api :measureText
这个 api 可以获取文本在实际渲染后的长度。具体使用方法如下:
// 需要获取宽度的文本
const text = '';
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
// 获取到的 metrics 对象中 width 即为要获取的宽度
const metrics = context.measureText(text);
const { width } = metrics;
使用 measureText
的时候,我们还可以设置 font 来达到自定义字体的效果。具体如下:
const text = '';
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
// 这里的 font 参考 canvas font api 可以来自定义一个字体
context.font = `normal normal ${fontWeight} ${fontSize}px ${fontFamily}`;
const metrics = context.measureText(text);
const { width } = metrics;
尾言
TextMetrics
对象中不仅仅包含一个 width
宽度,还有actualBoundingBoxLeft
、actualBoundingBoxRight
、fontBoundingBoxAscent
、fontBoundingBoxDescent
、actualBoundingBoxAscent
、actualBoundingBoxDescent
等属性,具体可以查看 mdn 对这些 api 的解释:
TextMetrics
我们可以设置 context.textBaseline = 'ideographic';
然后通过actualBoundingBoxAscent - actualBoundingBoxDescent
来获取单行文本的高度,不过该 api 在钉钉和飞书里使用目前存在问题,慎用。