Canvas possui o método MeasureText de texto para obter as informações de texto contidas no objeto TextMetrics. Através do TextMetrics, podemos obter diretamente o valor da largura do texto, mas não podemos obter diretamente o valor da altura.
Por exemplo, TextMetrics
TextMetrics.width somente leitura
Tipo duplo , a largura da string embutida em pixels CSS. Com base nas considerações atuais sobre fontes de contexto.
TextMetrics.actualBoundingBoxLeft (en-US) somente leitura
tipo double , paralelo à linha de base, a distância do ponto de alinhamento determinado pela propriedade CanvasRenderingContext2D.textAlign até o lado esquerdo do limite do retângulo de texto , calculado usando pixels CSS; um valor positivo indica que o lado esquerdo do limite do retângulo de texto é no lado esquerdo do ponto de alinhamento.
TextMetrics.actualBoundingBoxRight (en-US) somente leitura
tipo double , paralelo à linha de base, a distância do ponto de alinhamento determinado pela propriedade CanvasRenderingContext2D.textAlign até o lado direito da borda do retângulo de texto , calculada em pixels CSS.
TextMetrics.fontBoundingBoxAscent (en-US) mais recente
Tipo duplo , a distância da linha horizontal indicada pela propriedade CanvasRenderingContext2D.textBaseline até o topo da borda mais alta do retângulo de todas as fontes usadas para renderizar o texto , calculada em pixels CSS.
TextMetrics.fontBoundingBoxDescent (en-US) 只读
Tipo duplo , a distância da linha horizontal indicada pela propriedade CanvasRenderingContext2D.textBaseline até o limite inferior do retângulo de todas as fontes usadas para renderizar o texto, calculada usando pixels CSS.
TextMetrics.actualBoundingBoxAscent (en-US) somente leitura
Tipo duplo , a distância da linha horizontal indicada pela propriedade CanvasRenderingContext2D.textBaseline até o topo do retângulo que delimita o texto renderizado , calculada em pixels CSS.
TextMetrics.actualBoundingBoxDescent (en-US) somente leitura
Tipo duplo , a distância da linha horizontal indicada pela propriedade CanvasRenderingContext2D.textBaseline até a parte inferior do retângulo que delimita o texto renderizado , calculada em pixels CSS.
Referência: https://developer.mozilla.org/zh-CN/docs/Web/API/TextMetrics
Segundo, calcule a largura e a altura
<canvas id="canvas" width="550" height="500"></canvas>
1. Meça a largura do texto
Ao medir a largura horizontal de um trecho de texto, a soma da soma pode ser maior que a largura da caixa embutida ( ) devido às letras inclinadas/itálico que fazem com que os caracteres sejam mais largos do que a largura actualBoundingBoxLeft
pretendida .actualBoundingBoxRight
width
Portanto, calcular actualBoundingBoxLeft
a actualBoundingBoxRight
soma da soma é uma maneira mais precisa de obter a largura absoluta do texto:
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
2. Meça a altura do texto
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;
3. Exemplo de aplicação
1. Implemente texto multilinhas no 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. As tags HTML calculam a largura e a altura do texto
Nota: O tamanho mínimo da fonte pode ser apenas 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}`)