canvas绘图必须等二维码图片加载完成,用img.onload确保绘制时机;todataurl需显式指定mime类型和质量参数;文字渲染要处理换行和字体加载;跨域图片需cors支持或服务端代理。

canvas绘图前必须等二维码图片加载完成
直接用 drawImage() 绘制未加载完的二维码图片,结果是空白——这是最常踩的坑。Canvas 不会自动等待图片加载,img.onload 是唯一可靠时机。
- 用
new Image()创建图片对象,设置src后必须绑定onload回调再触发drawImage() - 若二维码由第三方库(如
qrcode.js)生成为data URL,仍需转成Image实例加载,不能直接传给drawImage() - 避免在
onload外部调用绘制逻辑;异步加载和同步绘图混用必然失败
用 toDataURL 生成海报图片时注意 MIME 类型和质量参数
toDataURL() 默认输出 image/png,但分享场景下常需压缩体积——这时得显式传参,否则 image/jpeg 质量默认为 0.92,且 PNG 不支持质量调节。
- 导出 JPEG:用
canvas.toDataURL('image/jpeg', 0.8),第二个参数是 0–1 的质量值(仅对 JPEG/JPG 生效) - 移动端微信内分享要求图片宽高比接近 1:1 或 3:4,建议 canvas 宽高设为 750×1000(适配 iPhone 屏宽),避免被裁切
- 部分安卓 WebView 对
toDataURL返回的长 base64 字符串截断,可改用canvas.toBlob()+URL.createObjectURL()替代
文字渲染要手动处理换行和字体加载延迟
Canvas 的 fillText() 不自动换行,中文长文本直接写会溢出;更隐蔽的问题是字体未就绪时渲染,导致文字位置偏移或使用默认字体(如“serif”)。
- 用
ctx.measureText()配合循环拆分字符串实现简易换行,每行宽度不超过设定阈值(如 500px) - 若用自定义字体(如 “PingFang SC”),需先用
document.fonts.load()等待加载完成,否则ctx.font设置无效 - 字号建议 ≥ 28px,小字号在手机上易糊;避免用
ctx.textAlign = 'center'后直接fillText(text, x, y),x 应为 canvas 中心而非文字中心——正确写法是x = canvas.width / 2
跨域图片(如用户头像)导致 toDataURL 失败
从其他域名加载的图片(如微信头像 URL)若没开 CORS,Canvas 会被污染,调用 toDataURL() 抛错:Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
- 服务端代理是最稳妥解法:把头像请求走自己后端,加
Access-Control-Allow-Origin: * - 前端临时方案:用
img.crossOrigin = 'anonymous',但前提是资源服务器真正支持 CORS,否则仍失败 - 本地开发时 Chrome 会因 file:// 协议拒绝跨域请求,务必起本地服务(如
python3 -m http.server)测试
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











