图片不显示主因是未等加载完成就绘制或参数错误;须在img.onload回调中调用drawImage(),正确使用2/4/9参数形式,跨域图需设crossOrigin='anonymous'并配服务端CORS头。

图片不显示,八成是没等加载完就画了,或者参数传错了顺序。
必须等 img.onload 触发后再调用 drawImage()
Image 对象是异步加载的,img.src = 'xxx.png' 之后立刻调用 drawImage(),图像数据大概率还没到位,画布上什么都不会出现,控制台也不报错。
- 错误写法:
const img = new Image(); img.src = 'logo.png'; ctx.drawImage(img, 0, 0); - 正确写法:把
drawImage()放进onload回调里,且src赋值要放在最后 - 如果图来自用户
File或Blob,用URL.createObjectURL(file)创建 URL 后,同样要监听onload
drawImage() 的三种参数形式别混用
参数个数决定行为,传错数量不会报错,但结果往往不是你想要的——比如图像被拉伸、偏移、甚至完全空白。
- 2 参数:
drawImage(img, x, y)—— 整图原尺寸,左上角对齐到(x, y) - 4 参数:
drawImage(img, x, y, width, height)—— 整图缩放到指定宽高,仍以(x, y)为左上角 - 9 参数:
drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)—— 先从源图裁剪(sx,sy,sw,sh)区域,再把它画到目标位置(dx,dy)并缩放到dw×dh
跨域图片要配 crossOrigin,否则 canvas 会被污染
从 CDN、API 或其他域名加载图片时,即使 drawImage() 看似成功,后续调用 ctx.getImageData() 或 toDataURL() 会直接抛 SecurityError,而且这个错误不会触发 img.onerror。
- 必须设置:
img.crossOrigin = 'anonymous'(同域也建议加) - 服务端必须返回
Access-Control-Allow-Origin响应头,否则预检失败,canvas 依然被污染 - 调试技巧:绘制后立即执行
ctx.getImageData(0, 0, 1, 1),报错即说明已污染
用另一个 canvas 当图像源时,得确认它已绘制完成
把 offscreenCanvas 或其他 元素传给 drawImage() 作第一个参数,没问题;但若源 canvas 还在 requestAnimationFrame 中绘制,或刚创建还没调用过 fillRect() 等操作,内容就是空的。
- 验证方式:
sourceCanvas.toDataURL()返回"data:,"就说明没内容 - 动画场景下,不要在
requestAnimationFrame开始时立刻 drawImage,等所有绘图命令执行完再调用 - 高频重绘时,考虑用离屏 canvas 预渲染,避免每帧重复计算
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











