图片不显示是因未等加载完成就调用 drawimage;必须用 img.onload 作为绘制入口,且 image 必须是首参、已加载的合法元素;drawimage 三类参数核心是区分源区域与目标区域坐标。

Canvas 绘图前必须等图片加载完成,drawImage 本身不处理异步,参数顺序错或时机不对,图就“画不出来”——不是 bug,是逻辑没对上。
为什么图片总不显示?先盯住 onload
图片通过 img.src 加载是异步的,drawImage 执行时如果 img 还没解码完,画布上就是空白。这不是方法问题,是时序问题。
-
img.onload是唯一可靠的绘制入口点,不能用setTimeout或直接跟在src = ...后面调用 - 如果图片来自
URL.createObjectURL()或fetch+createObjectURL,也要等onload,不能假设 Blob URL 立即可用 - 出错时检查控制台是否报
Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The image argument is not an instance of HTMLImageElement——说明传进去的不是已加载的HTMLImageElement
三种 drawImage 参数形式怎么选?看你要不要裁剪
别死记参数个数,记住两组坐标:「源区域」(从哪截)和「目标区域」(画到哪)。没裁剪需求,就用前两种;要抠图、做雪碧图、局部缩放,才用第三种。
-
drawImage(image, dx, dy):整图原尺寸,左上角落在(dx, dy)。适合图标、水印、固定尺寸贴图 -
drawImage(image, dx, dy, dWidth, dHeight):整图拉伸/压缩进指定矩形。注意非等比缩放会变形,dWidth/dHeight不一定等于原图宽高比 -
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight):先从源图(sx, sy)开始截sWidth × sHeight区域,再把它画到目标位置并缩放到dWidth × dHeight。常用于帧动画、UI 切图复用
常见参数错误:顺序颠倒、类型错位
最典型错误是把坐标当第一个参数,比如写成 drawImage(0, 0, img)。JS 引擎会把 0 当作 image,img 当作 dWidth,结果报类型错误或静默失败。
- 所有重载形式,
image必须是第一个参数,且必须是已加载的HTMLImageElement、HTMLCanvasElement、HTMLVideoElement或ImageBitmap - 传
canvas元素时,确保它已渲染内容(比如先ctx2.fillRect()过),否则画出来是空的 - 用
ImageBitmap时,需通过createImageBitmap()显式构造,不能直接 new Image() 后赋值
缩放和裁剪时容易忽略的边界细节
裁剪区域超出原图范围不会报错,但会只取有效部分;目标尺寸为 0 或负数会导致绘制被跳过——这些都不会抛异常,只会“没反应”。
-
sx + sWidth > image.width时,自动截断到右边界;sy + sHeight > image.height同理。想严格校验,得自己提前算 -
dWidth或dHeight小于等于 0,整个drawImage调用会被忽略(无报错),画布不变 - 用
video元素时,drawImage只抓当前帧,若视频未播放或暂停,可能画出黑帧或第一帧,需监听loadeddata或canplay事件
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











