canvas无内置竖排文字功能,需自建排版引擎:逐字测量、坐标计算、旋转英文、统一基线、处理标点与边界截断,并支持多列、字间距、弧线等进阶效果。

Canvas本身不提供“竖排文字”开关,要实现真正可控、可编程的竖排效果,必须自己构建文本排版逻辑——也就是所谓“自定义Canvas文本排版引擎”。它不是调用一个API就完事,而是通过逐字测量、坐标计算、绘制控制,把每个字符精准摆到指定位置。
核心思路:按字符拆解 + 垂直坐标递推
竖排本质是把原本横向排列的字符串,转为从上到下(或从下到上)、每字占一行的布局。Canvas没有自动换行或方向切换,所以得手动做三件事:
- 遍历字符串每个字符,用
ctx.measureText()获取单字宽度与高度(注意中英文差异) - 根据设定的起始点(如左上角X、底部Y)、行高、对齐方式,算出每个字的
fillText(x, y)坐标 - 中文正立、英文数字默认倒置——若需统一正立,对ASCII字符额外加
rotate(-90)并调整原点
关键细节处理
真实项目中容易踩坑的几个点:
-
中英文混排方向不一致:Canvas里汉字竖排是自然正立,但英文字母会侧躺(因字体设计),需单独判断
/[a-zA-Z0-9]/.test(char),对英文做旋转+位移补偿 -
标点符号位置偏移:中文顿号、句号等在竖排时应居中对齐字面,而非基线对齐,建议统一用
textBaseline = 'middle'+ 手动微调Y偏移 -
容器边界截断:需预判总高度是否超出画布,支持
maxLines限制或自动缩放字号(用二分法试配) -
行高与字宽关系:竖排时“行高”实际对应字与字之间的垂直间距,推荐设为
fontSize × 1.3~1.6,避免拥挤或松散
基础代码结构示意
一个轻量可用的竖排函数骨架:
function drawVerticalText(ctx, text, startX, startY, options = {}) {
const { fontSize = 24, lineHeight = fontSize * 1.4, textAlign = 'center', textBaseline = 'middle' } = options;
ctx.font = `${fontSize}px sans-serif`;
ctx.textAlign = textAlign;
ctx.textBaseline = textBaseline;
<p>for (let i = 0; i </p><pre class="brush:php;toolbar:false;">// 英文/数字正立处理
if (/[\u0041-\u005A\u0061-\u007A\u0030-\u0039]/.test(char)) {
ctx.save();
ctx.translate(x, y);
ctx.rotate(-Math.PI / 2);
ctx.fillText(char, 0, 0);
ctx.restore();
continue;
}
ctx.fillText(char, x, y);} }
进阶能力扩展方向
当基础竖排稳定后,可逐步加入这些实用功能:
- 支持
\n换行符,实现“多列竖排”(如古籍双栏) - 集成
letterSpacing(字间距)和lineGap(行间隙)独立控制 - 添加描边、阴影、渐变填充等视觉增强,复用
ctx.strokeStyle/ctx.shadow* - 结合
Path2D或裁剪区域(ctx.clip()),实现文字沿弧线竖排











