首页 > 解决方案 > 为什么 HTML5 画布的“TextMetrics”对象中的“width”和“actualBoundingBoxLeft + actualBoundingBoxRight”有区别?

问题描述

当我measureText如代码片段所示调用时,我得到以下结果:

{
  "width": 45.43333435058594,
  "actualBoundingBoxLeft": 0,
  "actualBoundingBoxRight": 45.35,
  "actualBoundingBoxAscent": 18,
  "actualBoundingBoxDescent": 0
}

如果为零,为什么width和之间有区别?actualBoundingBoxRightactualBoundingBoxLeft

c2d = document.getElementById('canvas').getContext('2d');
c2d.direction = 'ltr';
c2d.font = '24px serif';
console.log (c2d.measureText('TeX'));
<canvas id="canvas"></canvas>

标签: texthtml5-canvas2d

解决方案


希望我能得到你的要求,我会试一试。

width属性给出了文本的提前宽度。占用的空间不包括左侧和右侧轴承。

– 宽度属性

该内联框的宽度,以 CSS 像素为单位。(文本的前进宽度。)

– actualBoundingBoxLeft属性

从textAlign属性给定的对齐点到给定文本的边界矩形左侧的平行于基线的距离,以 CSS 像素为单位;正数表示从给定对齐点向左的距离。

它还给出了注释:

这个值和下一个值的总和 (actualBoundingBoxRight)可以比内联框的宽度 (width) 更宽,特别是对于字符超出其提前宽度的倾斜字体。

– actualBoundingBoxRight属性

从textAlign属性给定的对齐点到给定文本的边界矩形右侧的平行于基线的距离,以 CSS 像素为单位;正数表示从给定对齐点开始的距离。


一些例子

用画布的measuereText中的数据(正常左侧,斜体右侧)来记录这个时间: f

f 左右轴承和前进宽度

ERR:中间和底部宽度线(蓝色)的位置交换,但没有更新标签。对于图片中的标签,“中间”是“底部”,“底部”是“中间”。稍后我会争取时间上传新的。

尤其是倾斜的版本很好地展示了这一点。textBaseline之后的蓝线(灰色水平线)并从textAlign(灰色垂直线)开始显示字形的宽度值。这就是字体使“打字头”前进的程度。

边界框左/右是水平扩展的极端。如果将其视为矩形。上升和下降也是如此。他们是极端的向上/向下。但是,作为字体的“重叠”(字距调整等),它不是代表高级宽度的宽度因素。

盒子宽度的总和111 + 39 = 150只是。width72.28


至于你的样本,用这么小的字体很难捕捉到。(相对而言)。将 for 增加到 1024px 或任何可以提供更清晰结果的值。有如此小的分数和路径计算,以至于人们会错过微妙的像素分数。使用 1024 像素:

  actualBoundingBoxAscent  :  747
  ​actualBoundingBoxDescent :   14
  ​actualBoundingBoxLeft    :  -10
  ​actualBoundingBoxRight   : 1933.5
  ​width                    : 1938.5

考虑到总宽度,差异 (1933.5 + -10 = 1923.5) 仍然很小,但至少存在于服务对象中。

另一个示例+

在此处输入图像描述

正如人们所观察到的那样,字形使文本的前进速度远远超过它在绘制像素中所占的位置。甚至可能出现字形根本不推进文本的情况。它们仍然可以在文本中独立存在,但它的定义以某种方式适用于前一个字形......例如dấu hỏi上面的钩子宽度为零。

在此处输入图像描述

但有些仍被定义为推进字符,例如:

在此处输入图像描述

该示例的另一个有趣之处在于查看 Descent 如何为负(不低于textBaseline),并且 Ascent 也存在。从逻辑上讲,当一个人看它时,但可能是一个陷阱。

可以扩大画布上的测试,但必须仔细观察。距离我在洞穴工作太久了。这是一个近距离视图,但尚未验证或检查线条的精确度(精确到像素)。

如果它是正确的,它会显示一个细微的差异,在使用 24px 字体结束时宽度会增加。TeX

在此处输入图像描述


推荐阅读