测量文本的宽度和高度

在实现一些图表或者图形时,需要测量文本的宽度和高度。例如,当文本的宽度超过容器的宽度时,需要自动换行,或者当文本的高度超过容器的高度时,需要截断文本等。在这些情况下,需要测量文本的宽度和高度,以便根据文本的宽度和高度来调整文本容器的宽度和高度。

那么,如何测量文本的宽度和高度呢?本文将介绍使用 Canvas API 来测量文本的宽度和高度。

测量文本宽度

通常,测量文本的宽度,可以使用 Canvas 中提供的 measureText,如下代码:

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (ctx) {
  ctx.font = '12px Arial serif';
}

function getWidth(ctx: CanvasRenderingContext2D, txt: string) {
  const metrics = ctx.measureText(txt);
  return metrics.width;
}

但是,上述示例仅考虑了文本本身的宽度,而没有考虑文本周围的空白空间。因此,我们需要使用 actualBoundingBoxLeftactualBoundingBoxRight 属性来计算文本周围的空白空间。

actualBoundingBoxLeftCanvasRenderingContext2D.measureText() 方法返回的一个属性,它表示文本相对于绘制点的最左边边缘的偏移量,可以是负数。它的值不包括字体的左侧边距。如果文本中的字符没有左侧部分,则该值为 0actualBoundingBoxRight 同理。

将它们添加到文本宽度的计算中,如下代码所示:

function getWidth(ctx: CanvasRenderingContext2D, txt: string) {
  const metrics = ctx.measureText(txt);
  const actual = Math.abs(metrics.actualBoundingBoxLeft) + Math.abs(metrics.actualBoundingBoxRight);
  return Math.max(metrics.width, actual);
}

最后,如果文本样式包含粗体或斜体等效果,也需要考虑它们对文本宽度的影响。对上述代码改进如下:

interface TextStyle {
  /** 字体的名称,如Arial,Verdana等 */
  fontFamily?: string;
  /** 字体的大小,以像素为单位 */
  fontSize?: string;
  /** 字体的样式,可以是normal(普通)、italic(斜体)或者oblique(倾斜) */
  fontStyle?: string;
  /** 字体的粗细程度,可以是normal(普通)、bold(粗体)或者数值,如400、700等。 */
  fontWeight?: string;
}

function getWidth(ctx: CanvasRenderingContext2D, txt: string, style: TextStyle) {
  const originalFont = ctx.font;
  const { fontFamily = 'Arial', fontSize = '12px', fontStyle = 'normal', fontWeight = 'normal' } = style;
  ctx.font = `${fontStyle} ${fontWeight} ${fontSize} ${fontFamily}`;
  const metrics = ctx.measureText(txt);
  const actual = Math.abs(metrics.actualBoundingBoxLeft ?? 0) + Math.abs(metrics.actualBoundingBoxRight ?? 0);
  const width = Math.max(metrics.width, actual);
  ctx.font = originalFont;
  return width;
}

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (ctx) {
  const width = getWidth(ctx, 'Hello World', { fontFamily: 'Arial', fontSize: '16px', fontWeight: 'bold' });
  console.log(width);
}

在这个示例中,将 font 属性设置为 fontStyle fontWeight fontSize fontFamily 的组合。这样可以确保使用正确的字体样式来测量文本宽度。

测量文本高度

测量文本高度的方法与测量文本宽度的方法类似,只是使用的属性不同。测量文本高度,可以使用 actualBoundingBoxAscentactualBoundingBoxDescent 属性。

actualBoundingBoxAscentCanvasRenderingContext2D.measureText() 方法返回的一个属性,它表示文本相对于绘制点的最高点的偏移量,可以是负数。它的值不包括字体的上侧边距。如果文本中的字符没有上侧部分,则该值为 0actualBoundingBoxDescent 同理。

实现代码和测量文本宽度的代码类似,这里不再赘述。

总结

本文介绍了使用 Canvas API 来测量文本的宽度和高度。首先介绍了如何设置文本样式,包括字体、字号、字形和字重等属性,以及测量文本宽度和高度的方法。

在实际应用中,测量文本宽度和高度是非常有用的。例如,可以根据文本的宽度自适应调整文本容器的宽度,或者根据文本的高度调整行间距等。Canvas API 提供了便捷的方法来测量文本的宽度和高度,能够方便地满足各种需求。

参考资料

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注