ios canvas文字偏移的根本原因是textbaseline默认值不一致且未显式设置,必须设为'top'并配合dpr适配和draw回调才能准确定位。

为什么iOS上fillText文字总往左/上偏
不是字体没加载完,也不是ctx.font设错了——根本原因是 iOS Canvas 的 textBaseline 默认值在不同平台不一致,且未显式设置时会受系统字体渲染策略干扰。H5 和 Android 通常默认 'alphabetic',而 iOS(尤其微信小程序)常表现为 'ideographic' 或不稳定行为,导致 y 坐标基准线漂移。
常见错误写法:ctx.fillText('你好', 100, 200) —— 没设 textBaseline,y=200 实际落在文字“腰部”还是“底部”完全不可控。
- 必须显式设置
ctx.textBaseline = 'top'或'middle',推荐'top':y 值即文字顶部像素位置,最易预测 -
ctx.setTextAlign('center')只影响 x 方向对齐,和 y 偏移无关;x=100 时,文字水平中心才对齐到 100,别误以为是左边缘 - 避免用
'bottom'或'alphabetic',iOS 对这些值的实现差异大,真机调试时可能突然错位
setTextAlign设成 center 但文字还是靠左?
这是典型坐标理解偏差。setTextAlign('center') 不改变绘制逻辑,只改变锚点解释方式:它要求你传入的 x 是「文字水平中心应落的位置」,而不是左上角。如果你 canvas 宽度是 300,想让文字居中显示,x 应该是 150,不是 0 或 100。
用户要生成可打印的中文字帖/练习纸、导出多页 A4 PDF 报告,或把 SVG 设计稿零误差还原到 Canvas 时使用。本技能是「Canvas 内容工厂闭环」的总控,编排:网格渲染引擎(13 种教育网格+拼音标注) → 多页 PDF 导出(A4 合成) → SVG 精准复刻(坐标误差<0.001px)。触发词:生成字帖、练习纸、导出 PDF、SVG 转 Canvas、印刷级还原、A4 报告、米字格田字格。
- 错误:
ctx.setTextAlign('center'); ctx.fillText('标题', 0, 100)→ 文字中心强行对齐到 x=0,整体大幅左出界 - 正确:
ctx.setTextAlign('center'); ctx.fillText('标题', canvasWidth / 2, 100) - 若文字需相对某元素居中(比如图片右下角),先算出该区域中心坐标,再传给
fillText
iOS保存后文字位置“看起来”又偏了?
不是绘制错了,是保存时 canvas 像素尺寸和 CSS 尺寸没对齐。iOS 对 canvas.width/canvas.height 异常敏感:如果 canvas 元素 CSS 宽高是 300×200,但实际 width 属性仍是 300×200(未适配 DPR),文字在高分屏上会被拉伸或压缩,导致视觉偏移。
- 务必在创建 canvas 后立即设置物理像素尺寸:
const dpr = uni.getSystemInfoSync().pixelRatio; canvas.width = canvas.offsetWidth * dpr; canvas.height = canvas.offsetHeight * dpr; - 随后调用
ctx.scale(dpr, dpr),让所有坐标按比例缩放,此时fillText('x', 100, 100)才真正在物理像素 (100, 100) 处绘制 - 不执行 scale,直接按 CSS 像素画,iOS 会插值渲染,文字边缘模糊+位置漂移
真机调试时文字偶尔闪一下再偏移?
这是 canvas 绘制未等待完成就调用 canvasToTempFilePath 的典型表现。iOS 渲染队列更严格,ctx.draw() 是异步的,不加回调就保存,大概率截到空白或旧帧。
- 每次文字绘制后,必须写:
ctx.draw(true, () => { uni.canvasToTempFilePath({...}) }) -
true参数强制清空之前所有绘制任务,避免多帧叠加干扰 - 不要在
onReady里一次性画完所有内容就结束;旋转、写字、再旋转……每步都得draw(true, callback)
最易被忽略的是 DPR 适配和 draw 回调——这两点在 iOS 上缺一不可,否则文字偏移不是“有时”,而是“必然”。










