NodeJS中Canvas多行文本垂直居中实现方法
解决方案:自动计算多行文本垂直居中的Y坐标
当然可以搞定!其实canvas-multiline-text已经帮我们做了大部分文本排版的脏活,我们只需要利用它的计算结果来确定正确的Y坐标就行。核心思路是让文本块的中心和画布的中心重合,下面分两种方法来实现:
方法一:先测量再绘制(推荐)
这个方法先让工具计算出文本的实际高度(包括自动调整字体大小后的高度),再计算出垂直居中所需的Y坐标,最后正式绘制文本。
步骤拆解:
- 先调用
drawMultilineText但不绘制,获取最终使用的字体大小 - 用工具的
getLines方法拆分文本为多行,计算总高度 - 计算文本块的顶部Y坐标,确保整体垂直居中
- 正式绘制文本
修改后的代码:
const fs = require('fs') const { registerFont, createCanvas, loadImage } = require('canvas') // 额外导入getLines方法来拆分文本 const { drawMultilineText, getLines } = require('canvas-multiline-text') const width = 2000; const height = 2000; const canvas = createCanvas(width, height) const context = canvas.getContext('2d') // 填充画布背景 context.fillStyle = '#fff' context.fillRect(0, 0, width, height) // 基础文本样式 context.font = "normal 700 250px Arial"; context.textAlign = 'center' context.textBaseline = 'middle'; context.fillStyle = '#000' const targetText = "Hello World, this is a test"; const textMaxWidth = context.canvas.width - 20; const textMaxHeight = context.canvas.height - 20; const lineHeightRatio = 1.4; // 第一步:先计算最终使用的字体大小(不实际绘制) const fontSizeUsed = drawMultilineText( context, targetText, { rect: { x: 0, y: 0, width: textMaxWidth, height: textMaxHeight }, font: 'Arial', verbose: false, lineHeight: lineHeightRatio, minFontSize: 100, maxFontSize: 250, draw: false // 关键参数:只计算不绘制 } ) // 第二步:拆分文本为多行,计算总高度 const lines = getLines(context, targetText, { font: 'Arial', fontSize: fontSizeUsed, maxWidth: textMaxWidth, lineHeight: lineHeightRatio }) const totalTextHeight = lines.length * fontSizeUsed * lineHeightRatio; // 第三步:计算垂直居中的Y坐标(画布中心 - 文本块高度的一半) const rectY = (height - totalTextHeight) / 2; // 水平居中的X坐标(画布宽度 - 文本最大宽度的一半) const rectX = (width - textMaxWidth) / 2; // 第四步:正式绘制多行文本 drawMultilineText( context, targetText, { rect: { x: rectX, y: rectY, width: textMaxWidth, height: textMaxHeight }, font: 'Arial', verbose: true, lineHeight: lineHeightRatio, minFontSize: 100, maxFontSize: 250 } ) // 保存画布到文件(可选) fs.writeFileSync('centered-text.png', canvas.toBuffer())
方法二:利用工具的verbose输出(快速调试用)
如果你的drawMultilineText开启了verbose: true,它会在控制台输出文本的行数、最终字体大小等信息。你可以直接用这些数据手动计算,但这种方法不适合自动化场景,只适合临时调试:
比如控制台输出:
Lines drawn: 2, Font size used: 250
总高度 = 2 × 250 × 1.4 = 700
垂直居中Y坐标 = (2000 - 700)/2 = 650
关键说明:
draw: false参数:这个参数让工具只执行排版计算,不绘制到画布,避免了重复绘制的性能损耗- 文本总高度计算:
行数 × 最终字体大小 × 行高比例,这是canvas-multiline-text排版时的实际行高计算方式 - 水平居中:通过
rectX让文本块左右留出相等的空白,和垂直居中逻辑一致
这样不管你的文本是单个单词还是长句子,都能自动实现垂直居中啦!
内容的提问来源于stack exchange,提问作者userjmillohara
相关产品推荐
相关产品推荐

