You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 14:02:52