必须先调用 canvas.getContext('2d') 获取渲染上下文才能绘图,否则 fillRect 等方法静默失败;width/height 是逻辑尺寸,CSS 缩放会导致模糊;fillRect 绘实心、strokeRect 绘边框;clearRect 仅擦除像素,不重置状态。

canvas.getContext('2d') 必须先调用才能绘图
直接写 <canvas> 标签不会自动渲染任何图形,必须通过 JavaScript 获取 2D 渲染上下文。如果跳过这步,后续所有绘图方法(比如 fillRect)都会静默失败,控制台也不报错——这是新手最常卡住的地方。
实操建议:
- 确保
<canvas>元素已加载完成,推荐把脚本放在</body>前,或监听DOMContentLoaded - 检查返回值是否为
null:如果传入非'2d'字符串(如'webgl'),getContext可能返回null,需加判断 -
<canvas width="200" height="100">中的width和height是绘图坐标系尺寸,不是 CSS 显示尺寸;用 CSS 缩放会导致图像模糊
fillRect 和 strokeRect 的区别和适用场景
fillRect(x, y, width, height) 绘制实心矩形,strokeRect(x, y, width, height) 只画边框。两者参数顺序一致,但视觉效果差异明显,选错会导致“什么都没画出来”的错觉(比如背景色和填充色一样)。
常见错误现象:
立即学习“前端免费学习笔记(深入)”;
- 用了
fillRect但页面空白:检查fillStyle是否被设成透明色(如'rgba(0,0,0,0)')或与背景同色 - 用了
strokeRect但线条看不见:确认strokeStyle和lineWidth已设置(默认lineWidth是 1,颜色是黑色) - 矩形位置偏移:注意 canvas 坐标原点在左上角,
x和y是左上顶点,不是中心点
示例(绘制一个红色实心矩形):
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(10, 20, 150, 80);
clearRect 用来擦除局部区域,不是重置整个 canvas
想“重画”矩形时,有人会试图调用 ctx.clearRect(0, 0, canvas.width, canvas.height) 清空全画布,但这只是清掉像素,并不重置绘图状态(比如 fillStyle、lineWidth 还在)。更隐蔽的问题是:如果 canvas 被 CSS 放大了,clearRect 参数仍要传逻辑像素值,而非屏幕像素。
使用要点:
-
clearRect填充的是透明黑色(rgba(0,0,0,0)),所以它依赖 canvas 的 alpha 通道;若 canvas 设置了alpha: false(通过getContext('2d', { alpha: false })),则清除区域变成纯黑 - 只清除指定矩形区域,不影响其他已绘制内容——适合做简单动画帧擦除,但不适合复杂重绘逻辑
- 不要依赖
clearRect来“修复”坐标算错的问题;先定位x/y是否超出 canvas 范围(负值或过大都会导致不可见)
矩形绘制后不显示?优先检查 canvas 尺寸和父容器样式
最常被忽略的其实是 HTML/CSS 层面的问题:canvas 元素默认宽高为 300×150,如果没设 width/height 属性,或被 CSS max-width: 100% 拉伸,绘图就会挤压变形甚至消失。
排查步骤:
- 打开开发者工具,选中
<canvas>元素,在 Styles 面板看 computed 的width和height(CSS 像素)是否与getAttribute('width')返回的逻辑像素一致 - 临时加一行 CSS:
canvas { background: #eee; border: 1px solid #999; },确认 canvas 元素本身是否渲染出来了 - 检查父容器是否有
overflow: hidden或transform,可能裁剪掉部分绘图区域
canvas 绘图是即时的、无 DOM 节点的位图操作,一旦出问题,线索都在上下文状态和尺寸匹配上,而不是代码语法。



















