2025年canvas中计算文本的宽度和高度的方法

canvas中计算文本的宽度和高度的方法canvas 有 text 的 measureText 方法可以获取 TextMetrics 对象中包含了 text 的文字信息 通过 TextMetrics 我们可以直接获得文字的 width 值 但是却不能直接获得 height 值 一 TextMetrics TextMetrics width 只读 double 类型 使用 CSS 像素计算的内联字符串的宽度

大家好,我是讯享网,很高兴认识大家。

canvas有text的measureText方法可以获取TextMetrics对象中包含了text的文字信息。通过TextMetrics我们可以直接获得文字的width值,但是却不能直接获得height值。

一、TextMetrics

TextMetrics.width 只读

double 类型,使用 CSS 像素计算的内联字符串的宽度。基于当前上下文字体考虑。

TextMetrics.actualBoundingBoxLeft (en-US) 只读

double 类型,平行于基线,从CanvasRenderingContext2D.textAlign 属性确定的对齐点到文本矩形边界左侧的距离,使用 CSS 像素计算;正值表示文本矩形边界左侧在该对齐点的左侧。

TextMetrics.actualBoundingBoxRight (en-US) 只读

double 类型,平行于基线,从CanvasRenderingContext2D.textAlign 属性确定的对齐点到文本矩形边界右侧的距离,使用 CSS 像素计算。

TextMetrics.fontBoundingBoxAscent (en-US) 只读

double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到渲染文本的所有字体的矩形最高边界顶部的距离,使用 CSS 像素计算。

TextMetrics.fontBoundingBoxDescent (en-US) 只读

double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到渲染文本的所有字体的矩形边界最底部的距离,使用 CSS 像素计算。


讯享网

TextMetrics.actualBoundingBoxAscent (en-US) 只读

double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到渲染文本的矩形边界顶部的距离,使用 CSS 像素计算。

TextMetrics.actualBoundingBoxDescent (en-US) 只读

double 类型,从CanvasRenderingContext2D.textBaseline 属性标明的水平线到渲染文本的矩形边界底部的距离,使用 CSS 像素计算。

参考:https://developer.mozilla.org/zh-CN/docs/Web/API/TextMetrics

二、计算宽高

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

讯享网

 1、测量文本宽度

当测量一段文本的水平宽度时,由于字母倾斜/斜体导致字符的宽度可能超出其预定的宽度,因此 actualBoundingBoxLeft 和 actualBoundingBoxRight 的总和可能会比内联盒子的宽度(width)更大。

因此,计算 actualBoundingBoxLeft 和 actualBoundingBoxRight 的总和是一种更准确地获取文本绝对宽度的方法:

讯享网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.81 console.log( textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft, ); // 462.33 

2、测量文本高度

const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); const text = "Abcdefghijklmnop"; ctx.font = "italic 50px serif"; const textMetrics = ctx.measureText(text); // 所有字在这个字体下的高度 let fontHeight = textMetrics.fontBoundingBoxAscent + textMetrics.fontBoundingBoxDescent; // 当前文本字符串在这个字体下用的实际高度 let actualHeight = textMetrics.actualBoundingBoxAscent + textMetrics.actualBoundingBoxDescent; 

三、实例应用

1、canvas中实现多行文本

讯享网// canvas多行文本 ; (function (global) { "use strict"; / * * @param {*} showStroke 是否显示描边 * @param {*} text 文本 * @param {*} x 中心点x坐标 * @param {*} y 中心点y坐标 * @param {*} maxWidth 最大宽度 * @param {*} lineHeight 行高 * @returns */ global.CanvasRenderingContext2D.prototype.wrapText = function (showStroke, text, x, y, maxWidth, lineHeight) { if (typeof text != 'string' || typeof x != 'number' || typeof y != 'number') { return; } var context = this; var canvas = context.canvas; if (typeof maxWidth == 'undefined') { maxWidth = (canvas && canvas.width) || 300; } if (typeof lineHeight == 'undefined') { lineHeight = (canvas && parseInt(window.getComputedStyle(canvas).lineHeight)) || parseInt(window.getComputedStyle(document.body).lineHeight); } // 字符分隔为数组 var arrText = text.split(''); var line = ''; for (let n = 0; n < arrText.length; n++) { let testLine = line; // 换行符 if(arrText[n] === '\n') { showStroke && context.strokeText(line, x, y); context.fillText(line, x, y); line = ''; y += lineHeight; // 行高 } else { testLine = line + arrText[n]; let metrics = context.measureText(testLine, context.font); // 计算文本宽度 let testWidth = metrics.actualBoundingBoxRight + metrics.actualBoundingBoxLeft; if (testWidth > maxWidth && n > 0) { showStroke && context.strokeText(line, x, y); context.fillText(line, x, y); line = arrText[n]; y += lineHeight; } else { line = testLine; } } } showStroke && context.strokeText(line, x, y); context.fillText(line, x, y); }; })(window);
this.ctx.wrapText(true, '文本', 20, 20, 100, 20)

 

2、html标签计算文本宽高

注意:字体大小最小只能12px

讯享网/*
 * html计算文本宽高
 */
; (function (global) {
  "use strict";
 
  global.TextNode = function () {
 
    /
   * 
   * @param {*} text 文本
   * @param {*} font 字体样式
   * @param {*} width 标签宽度
   * @param {*} height 标签高度
   * @returns 
   */
    const _getTextWH = function (text, font, width, height) {
      const $span = global.document.createElement("span");
      $span.innerHTML = text

      // const spanTextNode = global.document.createTextNode(text);
      // $span.appendChild(spanTextNode);
      $span.setAttribute("style", `font: ${font}; white-space: pre-wrap; position: fixed; top: 0; left: 0; display: block; line-height: 1; width: ${width ? width : 'auto'}; height: ${height ? height : 'auto'}`);
 
 
      const $body = global.document.getElementsByTagName("body")[0];
      $body.appendChild($span);

      const spanRect = $span.getBoundingClientRect();
 
      $body.removeChild($span);

      // console.log(spanRect.width, spanRect.height)
 
      return {
        width: spanRect.width,
        height: spanRect.height
      }

    }.bind(this);
 
    let _txt = _getTextWH(...arguments);
    
    // console.log('_txt', _txt)

    return {
      width: _txt.width,
      height: _txt.height
    };
  };
 
})(window);
let _txt = TextNode('智能字幕', `${data.fontSize}px ${data.fontFamily}`)

小讯
上一篇 2025-01-11 22:23
下一篇 2025-02-17 12:26

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/66626.html