必须先用 getElementById 获取 canvas 元素再调用 getContext('2d'),注意大小写、引号、加载时机及多 canvas 独立调用。

怎么获取 canvas 的 2D 绘图上下文
没拿到 getContext('2d'),后面所有绘图操作都无效——这是新手卡住最多的地方。必须先通过 getElementById 拿到 canvas 元素,再调用这个方法,它返回的才是真正的绘图对象。
常见错误是:canvas 元素还没加载完就执行 JS,或者忘了加引号写成 getContext(2d)(会报 TypeError: Cannot read property 'fillRect' of null)。
- 确保 JS 在
</body>前执行,或监听DOMContentLoaded -
getContext('2d')区分大小写,必须是小写的'2d',不是'2D'或'twod' - 如果页面有多个 canvas,每个都要单独调用
getContext('2d'),返回值不共享
为什么 drawImage 画不出图片或只显示空白
drawImage 是最易出错的绘图函数之一,根本原因几乎都是“图片还没加载完成就调用了它”。浏览器异步加载图片,src 赋值后立即调用 drawImage,此时图片数据为空。
- 必须等图片
onload触发后再绘图,不能靠setTimeout猜时间 - 如果图片来自跨域 URL(比如 CDN),需设置
img.crossOrigin = 'anonymous',否则会触发安全错误:Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The image argument is a canvas whose origin-clean flag is false. -
drawImage有 3 种参数形式,传错数量或类型(比如把数字当Image对象)会导致静默失败
clearRect 不清屏?或者清掉了不该清的内容
clearRect 只清除指定矩形区域的像素,不是“重置整个 canvas 状态”。很多人误以为它会清掉路径、颜色、线宽等设置,其实不会——那些属于绘图上下文的状态,得手动重设。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
立即学习“前端免费学习笔记(深入)”;
- 要清全屏:用
clearRect(0, 0, canvas.width, canvas.height),注意别用clientWidth/clientHeight,它们可能和 canvas 实际像素尺寸不一致(受 CSS 缩放影响) - 清除后若再画图颜色不对,大概率是之前设置的
fillStyle或strokeStyle还在生效,需要重新赋值 - 如果 canvas 有 CSS width/height 缩放,
clearRect仍按 canvas 内部像素尺寸计算,容易清偏——建议统一用canvas.width和canvas.height作为坐标系基准
requestAnimationFrame 里反复 draw 但动画卡顿或撕裂
用 requestAnimationFrame 做动画时,卡顿往往不是因为帧率低,而是重复绘制未清理、状态未重置,或意外触发 layout(比如读取 offsetWidth)。
- 每次动画帧开始前,必须调用
clearRect(或用putImageData备份恢复),否则上一帧残留会叠加 - 避免在循环中频繁创建对象(如 new Path2D()、new Image()),复用已有实例
- 不要在动画回调里读取
getBoundingClientRect()或任何触发重排的属性;如果必须响应尺寸变化,用ResizeObserver单独处理
canvas 的“绑定绘图”本质就是状态机管理:上下文对象存着当前颜色、线条样式、变换矩阵……漏掉一次 reset,后续所有绘制都会偏移或变色。最容易被忽略的,是 CSS 尺寸和 canvas 内部像素尺寸的隐式不一致——它不会报错,但会让 clearRect 和 drawImage 表现诡异。


















