HTML5 画布中的居中(比例字体)文本

问题描述 投票:0回答:7

我希望能够在我可以计算的矩形区域内将单行文本居中。我期望在画布上的 2D 几何中做的一件事是将宽度未知的东西居中。

我听说有一种解决方法,您可以在 HTML 容器中创建文本,然后调用 jQuery 的

width()
函数,但我?没有正确处理文档正文的瞬时添加?宽度为 0。

如果我有一行文本,明显短于填充屏幕中大部分宽度,我如何知道它在画布上以我知道的字体大小有多宽?

javascript jquery html canvas fonts
7个回答
60
投票

您可以使用 measureText

来完成此操作
var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d")

canvas.width = 400;
canvas.height = 200;

ctx.fillStyle = "#003300";
ctx.font = '20px sans-serif';

var textString = "Hello look at me!!!",
    textWidth = ctx.measureText(textString ).width;


ctx.fillText(textString , (canvas.width/2) - (textWidth / 2), 100);

现场演示

更详细的演示


48
投票

如果您不一定需要文本的宽度,而只是想让文本居中,您可以这样做

canvas_context.textBaseline = "middle";
canvas_context.textAlign = "center";

这应该将文本垂直和水平居中。

请参阅 MDN 的 textAligntextBaseline 了解有关图片的更多信息


25
投票

developer.mozilla.org

textAlign
描述中说明 对齐基于上下文的 fillText() 方法的
x 值
。也就是说,该属性不会使画布中的文本水平居中;它将文本围绕给定的 x 坐标居中。类似的情况也适用于
textBaseLine

因此,为了使文本在两个方向上居中,我们需要设置这些 两个属性并将文本放置在画布的中间。

ctx.textBaseline = 'middle'; 
ctx.textAlign = 'center'; 

ctx.fillText('Game over', canvas_width/2, canvas_height/2);

3
投票

为了水平居中,我们使用

ctx.textBaseline = 'middle'; ctx.textAlign = 'center';
。但要垂直居中,我们需要使用
ctx.measureText

(actualBoundingBoxAscent - actualBoundingBoxDescent) / 2
很重要,因为对于不同的字体,文本可以以不同的方式垂直对齐。

// https://stackoverflow.com/questions/8696631/canvas-drawings-like-lines-are-blurry/59143499#59143499
function setCanvas(canvas, w, h) {
    canvas.style.width = w + 'px';
    canvas.style.height = h + 'px';
    const scale = window.devicePixelRatio;
    canvas.width = w * scale;
    canvas.height = h * scale;
    const ctx = canvas.getContext('2d');
    ctx.scale(scale, scale);
}

const width = 160;
const height = 160;
const fontSize = 100;
const text = 'A';

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

setCanvas(canvas, width, height); 

ctx.fillStyle = 'red';
ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.fillStyle = 'white';
ctx.font = `${fontSize}px sans-serif`;
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
let { actualBoundingBoxAscent, actualBoundingBoxDescent } = ctx.measureText(text);
ctx.fillText(text, width / 2, height / 2 + (actualBoundingBoxAscent - actualBoundingBoxDescent) / 2);
canvas{
  outline: 1px black solid
 }
<canvas><canvas>


1
投票

您可以使用 ctx.textAlign = "center"; 将项目对齐到中心

var canva = document.getElementById("canvas");
ctx.textAlign = "center"; // To Align Center
ctx.font = "40px Arial"; // To change font size and type
ctx.fillStyle = '#313439'; // To give font 
ctx.fillText("Text Center", 150 ,80);

0
投票

对于那些想知道如何正确对齐高度的人,因为

measureText()
不会返回高度 (!)。

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

const centered = (text, size) => {
  ctx.font = size + 'px monospace';
  let s = ctx.measureText(text).width;
  ctx.fillText(text, canvas.width / 2 - s / 2, canvas.height / 2 + size / 4);
}  
    
/* Just for the demo, really! 
 * Please don't do this!
 * Use proper animation frames requests
 * and clear timeout(s)!!! */
[["is", 40], ["able",45], ["<-- to -->",50], ["FLEX", 55], [" SMOOTH!", 58], ["FLEX!!", 62], ["FLEX!!!", 63] ].forEach((e) => {
  setTimeout(() => {
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    centered(e[0], e[1])
  }, e[1]*100)
})

// Intro test
centered("CANFLEX", 50)
canvas{
  outline: 1px black solid
 }
<canvas><canvas>


-6
投票

您所做的就是使用负文本缩进将文本渲染到屏幕外,然后获取大小。

text-indent: -9999px

参见:使用“文本缩进”隐藏文本

© www.soinside.com 2019 - 2024. All rights reserved.