canvas文本自动居中需用measuretext精确测宽再反推起点,水平居中公式为x=centrex-metrics.width/2,垂直居中应结合actualboundingboxascent与descent计算y坐标,避免字体未设置、变量拼错等常见错误。

Canvas 文本自动居中,核心不是“把文字丢到中间”,而是让文字的视觉中心和画布中心对齐。这依赖两个关键动作:准确测出文字宽度,并据此反推绘制起点。而 measureText() 就是完成前半步的唯一可靠工具。
为什么必须用 measureText?
Canvas 的 fillText(text, x, y) 总是以左边缘为锚点绘制,x 坐标对应的是文字最左侧的位置。如果你直接传入画布中心 x 值,文字会从中心往右延伸——整体偏右。要让它“看起来居中”,就得把起始点往左挪半个字宽。这个“半个字宽”无法靠猜测或字体大小估算,因为不同字符(如 "i" 和 "W")、不同字体、甚至不同浏览器渲染下,实际宽度都不同。只有 ctx.measureText(text).width 能返回当前上下文下该字符串的真实像素宽度。
水平居中的标准写法
步骤清晰、缺一不可:
- 先确保
ctx.font已显式设置(例如ctx.font = '20px sans-serif'),否则measureText可能返回默认字体下的不可靠值 - 调用
const metrics = ctx.measureText(text)获取TextMetrics对象 - 计算起始横坐标:
x = centreX - metrics.width / 2 - 调用
ctx.fillText(text, x, y),其中 y 是基线位置(不是文字顶部)
垂直方向怎么才算“居中”?
水平居中靠宽度,垂直居中靠字体度量。textBaseline = 'middle' 看似简单,但实际会让基线落在字体中线,而不同字体的 ascender/descent 分布不均,常导致视觉偏高。更稳妥的方式是结合 metrics.actualBoundingBoxAscent 和 actualBoundingBoxDescent(现代浏览器支持):
- 获取完整边界高度:
const height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent - 计算基线应处的 y 坐标:
y = centreY + (metrics.actualBoundingBoxDescent - height / 2) - 这样文字的视觉重心就真正对齐画布中心纵轴
常见陷阱提醒
这些细节看似微小,却常导致文字消失或错位:
-
变量名拼写错误:比如把
centreX写成centerX或cenreX,结果x变成NaN,fillText不报错但不显示 -
忘记设字体:未设置
ctx.font时,measureText和实际绘制可能用不同字体,宽度与渲染不匹配 -
y 坐标过小:例如
y = 0或y = 10,文字基线在画布外,内容被裁剪 -
混淆 textBaseline 含义:设成
'top'或'bottom'时,y 对应的是顶边或底边,不是基线,需重新调整数值











