我希望能够在可以计算的矩形区域内居中单行文本。在2D画布上,唯一需要做的事情就是居中一个宽度未知的东西。
我听说可以通过在HTML容器中创建文本,然后调用jQuery的width()
函数来解决这个问题,但我没有正确处理文档主体的瞬时添加,得到了0的宽度。
如果我有一行单独的文本,远远比屏幕上填充大部分宽度的文本要短,那么我如何知道在我所知道的字体大小下它的宽度?
我希望能够在可以计算的矩形区域内居中单行文本。在2D画布上,唯一需要做的事情就是居中一个宽度未知的东西。
我听说可以通过在HTML容器中创建文本,然后调用jQuery的width()
函数来解决这个问题,但我没有正确处理文档主体的瞬时添加,得到了0的宽度。
如果我有一行单独的文本,远远比屏幕上填充大部分宽度的文本要短,那么我如何知道在我所知道的字体大小下它的宽度?
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);
ctx.fillText(textString , (canvas.width/2) - (textWidth / 2), canvas.height/2);
可能会看起来更好。 - Loktar canvas_context.textBaseline = 'middle';
canvas_context.textAlign = "center";
developer.mozilla.org在textAlign
的描述中指出,文本的对齐是基于上下文的fillText()
方法的x值。也就是说,该属性不会在画布中水平居中文本,而是将文本围绕给定的x坐标居中。类似地,textBaseLine
也是如此。
因此,为了使文本在两个方向上居中,我们需要设置这两个属性并将文本定位于画布的中心。
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.fillText('Game over', canvas_width/2, canvas_height/2);
要水平居中,我们使用 ctx.textBaseline = 'middle'; ctx.textAlign = 'center';
。但是要垂直居中,我们需要使用 ctx.measureText
。
(actualBoundingBoxAscent - actualBoundingBoxDescent) / 2
很重要,因为对于不同字体的文本,其垂直对齐方式可能会有所不同。
// https://dev59.com/Zmoy5IYBdhLWcg3wN7e8#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>
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);
对于那些想知道如何正确对齐高度的人,因为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>