canvas-id必须显式声明且全局唯一,否则uni.createCanvasContext报错或canvasToTempFilePath返回空图;网络图片须先getImageInfo再drawImage;ctx.draw()需配合回调确保绘制完成;保存必须用uni.canvasToTempFilePath而非toDataURL。

canvas-id 必须显式声明且全局唯一
不设 canvas-id,uni.createCanvasContext 会直接报错“canvas-id attribute is undefined”;设了但重复或拼错,后续 canvasToTempFilePath 就返回空图或 “fail canvas is empty”。这不是警告,是硬性约束。
-
canvas-id值必须和uni.createCanvasContext第一个参数完全一致(区分大小写) - 不能用
id替代canvas-id——<canvas id="xxx"></canvas>是无效的 - 多个海报组件共存时,每个
canvas的canvas-id要不同,比如"posterCanvas1"、"posterCanvas2" - H5 端若用
<canvas type="2d"></canvas>,会彻底失效,必须用默认 type(即不写 type)
网络图片必须先 uni.getImageInfo 再绘制
直接传 https://xxx.png 给 ctx.drawImage,iOS 和大部分安卓机上会静默失败——图不显示,也不报错,海报就缺一块。原因:Canvas API 不支持跨域网络图直绘,uni-app 也没帮你兜底。
- 必须先调
uni.getImageInfo({ src: 'https://...' }),等 success 回调拿到res.path(本地临时路径)后再传给drawImage - 二维码、商品图、用户头像这类动态 URL,都要走这一步,不能省
- 多张图要逐个加载,或用
Promise.all控制并发,避免ctx.draw()提前触发
ctx.draw() 的时机和回调必须配对使用
漏掉 ctx.draw(),所有绘制命令只是“记在内存里”,画布仍是空白;但若没等图片加载完就调 ctx.draw(),或者没用它的回调就急着转图,就会截到半成品——文字有了,图还没刷上去。
- 所有异步资源(如
getImageInfo、getSystemInfo)完成后,再执行ctx.draw(false, () => { ... }) -
false表示不立即刷新,配合回调确保绘制真正完成 - 不要在
onReady里直接画——此时 DOM 可能未就绪,尤其带条件渲染的 canvas - 调试时可在回调里加
console.log('draw done'),确认是否真执行了
保存前务必用 uni.canvasToTempFilePath 而非 toDataURL
ctx.toDataURL() 在 uni-app 所有端都不支持,强行调用会报 undefined is not a function;而 uni.canvasToTempFilePath 是跨端唯一可靠出口,但它依赖 canvas 实际渲染完毕,且参数稍有偏差就失败。
- 必须传
canvasId,且和模板中一致 - 宽高单位是 px,不是 rpx;若 canvas 宽高用 rpx 设置,这里要换算成实际像素(可用
uni.upx2px(750)辅助) - 安卓部分机型对 canvas 尺寸敏感,建议宽度 ≤ 1200px,高度 ≤ 2000px,否则生成失败无提示
- 生成成功后得到
tempFilePath,才能传给uni.saveImageToPhotosAlbum,别试图用 data URL 中转

















