TextMetrics

Baseline 广泛可用 *

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

* 此特性的某些部分可能存在不同级别的支持。

注意:此功能在 Web Workers 中可用。

TextMetrics 接口代表画布中文本的尺寸;可以通过 CanvasRenderingContext2D.measureText() 方法获取 TextMetrics 实例。

实例属性

TextMetrics.width 只读

返回画布中文本片段的宽度(以 CSS 像素为单位)。它会考虑画布的当前字体。

TextMetrics.actualBoundingBoxLeft 只读

文本的实际边界框左侧到由 CanvasRenderingContext2D.textAlign 属性指定的对齐点之间的距离,测量方向与基线平行(以 CSS 像素为单位);正值表示从指定的对齐点向左的距离。

TextMetrics.actualBoundingBoxRight 只读

文本的实际边界框右侧到由 CanvasRenderingContext2D.textAlign 属性指定的对齐点之间的距离,测量方向与基线平行(以 CSS 像素为单位)。

TextMetrics.fontBoundingBoxAscent 只读

CanvasRenderingContext2D.textBaseline 属性指示的水平线到渲染文本所使用的所有字体的最高边界矩形的顶部之间的距离(以 CSS 像素为单位)。

TextMetrics.fontBoundingBoxDescent 只读

CanvasRenderingContext2D.textBaseline 属性指示的水平线到渲染文本所使用的所有字体的边界矩形的底部之间的距离(以 CSS 像素为单位)。

TextMetrics.actualBoundingBoxAscent 只读

CanvasRenderingContext2D.textBaseline 属性指示的水平线到渲染文本所使用的边界矩形的顶部之间的距离(以 CSS 像素为单位)。

TextMetrics.actualBoundingBoxDescent 只读

CanvasRenderingContext2D.textBaseline 属性指示的水平线到渲染文本所使用的边界矩形的底部之间的距离(以 CSS 像素为单位)。

TextMetrics.emHeightAscent 只读

CanvasRenderingContext2D.textBaseline 属性指示的水平线到行框中 em 方形顶部的距离(以 CSS 像素为单位)。

TextMetrics.emHeightDescent 只读

CanvasRenderingContext2D.textBaseline 属性指示的水平线到行框中 em 方形底部的距离(以 CSS 像素为单位)。

TextMetrics.hangingBaseline 只读

CanvasRenderingContext2D.textBaseline 属性指示的水平线到行框的悬挂基线之间的距离(以 CSS 像素为单位)。

TextMetrics.alphabeticBaseline 只读

CanvasRenderingContext2D.textBaseline 属性指示的水平线到行框的 字母基线 之间的距离(以 CSS 像素为单位)。

TextMetrics.ideographicBaseline 只读

CanvasRenderingContext2D.textBaseline 属性指示的水平线到行框的表意文字基线之间的距离(以 CSS 像素为单位)。

示例

基线图示

此示例演示了 TextMetrics 对象持有的基线。默认基线是 alphabeticBaseline。另请参阅 CanvasRenderingContext2D.textBaseline 属性。

HTML

html
<canvas id="canvas" width="550" height="500"></canvas>

JavaScript

js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const baselinesAboveAlphabetic = [
  "fontBoundingBoxAscent",
  "actualBoundingBoxAscent",
  "emHeightAscent",
  "hangingBaseline",
];
const baselinesBelowAlphabetic = [
  "ideographicBaseline",
  "emHeightDescent",
  "actualBoundingBoxDescent",
  "fontBoundingBoxDescent",
];
const baselines = [...baselinesAboveAlphabetic, ...baselinesBelowAlphabetic];
ctx.font = "25px serif";
ctx.strokeStyle = "red";

baselines.forEach((baseline, index) => {
  const text = `Abcdefghijklmnop (${baseline})`;
  const textMetrics = ctx.measureText(text);
  const y = 50 + index * 50;
  ctx.beginPath();
  ctx.fillText(text, 0, y);

  const baselineMetricValue = textMetrics[baseline];
  if (baselineMetricValue === undefined) {
    return;
  }

  const lineY = baselinesBelowAlphabetic.includes(baseline)
    ? y + Math.abs(baselineMetricValue)
    : y - Math.abs(baselineMetricValue);
  ctx.moveTo(0, lineY);
  ctx.lineTo(550, lineY);
  ctx.stroke();
});

结果

测量文本宽度

在测量文本的 x 方向时,由于斜体/倾斜字体中字符的悬垂部分可能会超出其前进宽度,因此 actualBoundingBoxLeftactualBoundingBoxRight 的总和可能比行内框的宽度 (width) 更宽。

因此,使用 actualBoundingBoxLeftactualBoundingBoxRight 的总和作为获取绝对文本宽度的更准确方法可能很有用。

js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const text = "Abcdefghijklmnop";
ctx.font = "italic 50px serif";
const textMetrics = ctx.measureText(text);

console.log(textMetrics.width);
// 459.8833312988281

console.log(
  textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft,
);
// 462.8833333333333

规范

规范
HTML
# textmetrics

浏览器兼容性

另见