canvas导出图片需确保资源加载完成且处理跨域,优先用toblob()避免base64过大;drawimage须在img.onload中执行;高dpr设备需缩放canvas并调用ctx.scale()适配。

Canvas 本身不能直接“生成海报图片”,它只是画布;真正导出图片靠的是 toDataURL() 或 toBlob(),且必须确保所有资源(尤其是图片)已加载完成,否则 canvas 是空的或报错。
为什么 drawImage 后 canvas 是空白?—— 图片跨域和加载时机问题
最常见的情况:用 new Image() 加载本地或第三方图片后立刻 ctx.drawImage(),结果 canvas 没内容。这是因为图片是异步加载的,drawImage 执行时图片还没到位。
- 必须把绘图逻辑写在
img.onload回调里,或用Promise封装加载过程 - 如果图片来自其他域名(如 CDN),需设置
img.crossOrigin = 'anonymous',否则toDataURL()会抛出SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement' - 本地 file:// 协议下部分浏览器会直接拒绝跨域请求,调试建议起一个本地服务(如
npx serve)
如何正确导出为 PNG/JPEG?—— toDataURL 和 toBlob 的选择
toDataURL() 返回 base64 字符串,适合小图预览或嵌入 HTML;toBlob() 更实用,能直接生成 Blob 对象用于下载或上传。
用户要生成可打印的中文字帖/练习纸、导出多页 A4 PDF 报告,或把 SVG 设计稿零误差还原到 Canvas 时使用。本技能是「Canvas 内容工厂闭环」的总控,编排:网格渲染引擎(13 种教育网格+拼音标注) → 多页 PDF 导出(A4 合成) → SVG 精准复刻(坐标误差<0.001px)。触发词:生成字帖、练习纸、导出 PDF、SVG 转 Canvas、印刷级还原、A4 报告、米字格田字格。
-
canvas.toDataURL('image/png')—— 默认格式,无损,支持透明通道 -
canvas.toDataURL('image/jpeg', 0.9)—— JPEG 不支持透明,第二个参数是质量(0–1),推荐 0.8–0.9 平衡体积与清晰度 -
canvas.toBlob(callback, 'image/png')—— 异步,callback 接收Blob,配合URL.createObjectURL()可生成可下载链接 - 注意:Safari 旧版本不支持
toBlob,可用toDataURL+fetch+blob回退
文字渲染模糊?—— 像素对齐和 devicePixelRatio 陷阱
在 Retina 屏或高 DPI 设备上,直接按 CSS 宽高设置 canvas,文字/线条容易发虚。因为 canvas 的「绘图分辨率」和「显示分辨率」被浏览器自动缩放了。
- 获取真实像素尺寸:
const dpr = window.devicePixelRatio || 1; - 设置 canvas 的
width/height属性为cssWidth * dpr,再用 CSS 缩放到目标尺寸:canvas.style.width = cssWidth + 'px'; - 调用
ctx.scale(dpr, dpr)后,所有坐标、字号按 CSS 尺寸写即可,避免手动乘 dpr - 字体建议用整数字号(如
ctx.font = '24px sans-serif'),避免小数导致亚像素渲染模糊
真正难的不是画什么,而是让每张图在不同设备、不同来源图片、不同网络环境下都稳定导出——资源加载控制、跨域策略、DPR 适配、格式兼容,缺一不可。漏掉任一环,用户点“保存海报”就卡在白图或报错里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










