如何渲染内容前获取文本宽度

795 阅读1分钟

如何在内容渲染前获取文本宽度?canvas 的 measureText 了解一下。

前言

在我们开发过程中,有时候需要获取文本实际在页面中的内容宽度,通常的做法是,使用Element.getBoundingClientRect()获取到的 width,即为当前元素在浏览器中展示的实际宽度。

image.png

该方法返回的 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 宽度,还有actualBoundingBoxLeftactualBoundingBoxRightfontBoundingBoxAscentfontBoundingBoxDescentactualBoundingBoxAscentactualBoundingBoxDescent等属性,具体可以查看 mdn 对这些 api 的解释: TextMetrics

我们可以设置 context.textBaseline = 'ideographic';然后通过actualBoundingBoxAscent - actualBoundingBoxDescent来获取单行文本的高度,不过该 api 在钉钉和飞书里使用目前存在问题,慎用。