如何在 HTML 画布上找到文本的高度?

2022-08-30 02:04:40

该规范有一个 context.measureText(text) 函数,该函数将告诉您打印该文本需要多大的宽度,但我找不到一种方法来找出它有多高。我知道它基于字体,但我不知道将字体字符串转换为文本高度。


答案 1

更新 - 对于这项工作的示例,我在Carota编辑器中使用了这种技术。

根据ellibben的回答,这里有一个增强的版本,用于从基线上升和下降,即与Win32的GetTextMetric API相同并由其返回。如果要执行具有不同字体/大小的跨度的文字换行文本,则需要执行此操作。tmAscenttmDescent

Big Text on canvas with metric lines

上面的图像是在 Safari 中的画布上生成的,红色是画布被告知绘制文本的顶线,绿色是基线,蓝色是底部(所以红色到蓝色是全高)。

使用jQuery来简洁:

var getTextHeight = function(font) {

  var text = $('<span>Hg</span>').css({ fontFamily: font });
  var block = $('<div style="display: inline-block; width: 1px; height: 0px;"></div>');

  var div = $('<div></div>');
  div.append(text, block);

  var body = $('body');
  body.append(div);

  try {

    var result = {};

    block.css({ verticalAlign: 'baseline' });
    result.ascent = block.offset().top - text.offset().top;

    block.css({ verticalAlign: 'bottom' });
    result.height = block.offset().top - text.offset().top;

    result.descent = result.height - result.ascent;

  } finally {
    div.remove();
  }

  return result;
};

除了文本元素之外,我还添加了一个 div,以便我可以设置其样式,然后找出浏览器放置它的位置。display: inline-blockvertical-align

所以你得到一个带有 和 的对象(为了方便起见,这只是 +)。为了测试它,值得有一个绘制水平线的函数:ascentdescentheightascentdescent

var testLine = function(ctx, x, y, len, style) {
  ctx.strokeStyle = style; 
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.lineTo(x + len, y);
  ctx.closePath();
  ctx.stroke();
};

然后,您可以看到文本在画布上相对于顶部、基线和底部的位置:

var font = '36pt Times';
var message = 'Big Text';

ctx.fillStyle = 'black';
ctx.textAlign = 'left';
ctx.textBaseline = 'top'; // important!
ctx.font = font;
ctx.fillText(message, x, y);

// Canvas can tell us the width
var w = ctx.measureText(message).width;

// New function gets the other info we need
var h = getTextHeight(font);

testLine(ctx, x, y, w, 'red');
testLine(ctx, x, y + h.ascent, w, 'green');
testLine(ctx, x, y + h.height, w, 'blue');

答案 2

浏览器开始支持高级文本指标,当此任务得到广泛支持时,这将使它变得微不足道:

let metrics = ctx.measureText(text);
let fontHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;
let actualHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;

fontHeight获取边界框高度,无论呈现的字符串如何,该高度都是常数。 特定于要呈现的字符串。actualHeight

规格:https://www.w3.org/TR/2012/CR-2dcontext-20121217/#dom-textmetrics-fontboundingboxascent 及其下方的部分。

支持状态 (2017 年 8 月 20 日):