用<canvas>画矩形需先获取2d上下文,再调fillRect(x,y,width,height);stroke()需先beginPath()定义路径;动画需clearRect清屏;跨域图片导出前须设crossOrigin。

怎么用 <canvas> 画第一个矩形
Canvas 不是「放图的地方」,它是一块空白画布,所有图形都得靠 JavaScript 一笔一笔画出来。直接写 <canvas width="200" height="100"></canvas> 页面上啥也看不到——因为没调用绘图 API。
必须先拿到上下文(通常是 2d),再调用绘图方法:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#ff6b6b';
ctx.fillRect(10, 10, 80, 40);
-
fillRect()是最基础的绘制函数,参数顺序是x、y、width、height,原点在左上角 - 如果没调
getContext('2d')就直接操作ctx,会报TypeError: Cannot read property 'fillRect' of null - Canvas 的
width和height属性必须用 HTML 属性写,不能只靠 CSS;否则图像会被拉伸变形
为什么 stroke() 没画出线条
Canvas 的路径绘制是「两步走」:先定义路径(比如用 beginPath()、moveTo()、lineTo()),再描边或填充。漏掉任意一步,就什么也不出现。
常见错误是只调了 lineTo() 就直接 stroke(),结果空白:
立即学习“前端免费学习笔记(深入)”;
ctx.beginPath(); ctx.moveTo(20, 20); ctx.lineTo(100, 20); ctx.stroke(); // ✅ 正确
- 每次画新路径前建议显式调
beginPath(),否则旧路径可能被重复描边 -
stroke()默认颜色是黑色、线宽是 1px;如果背景也是黑的,就「看不见」——记得设ctx.strokeStyle或ctx.lineWidth -
stroke()和fill()不会自动清空路径,但beginPath()会重置当前路径
requestAnimationFrame() 动画卡顿的真正原因
Canvas 动画不是“每帧重画整个画布”就完事,性能瓶颈常出在没清理旧内容或反复创建对象上。
- 每一帧开头必须清屏,常用
ctx.clearRect(0, 0, canvas.width, canvas.height);用fillRect()盖白底会触发合成层切换,更慢 - 避免在动画循环里新建
Path2D、重复解析字符串颜色、或调getBoundingClientRect() - 如果画布尺寸随窗口变化,请用
resize事件重新设置canvas.width/canvas.height(注意:这会清空画布) - 移动端要注意:
requestAnimationFrame()在后台标签页会降频甚至暂停,别依赖它做精确计时
导出图片时 toDataURL() 返回空字符串
这个错误几乎只发生在跨域图片绘制后立即导出——Canvas 被污染(tainted)了,安全策略禁止读取像素数据。
- 只要用
ctx.drawImage(img, ...)绘制过一张未声明crossOrigin的远程图片,后续调toDataURL()或getImageData()就会报SecurityError或返回空串 - 修复方式:图片加载前加
img.crossOrigin = 'anonymous',且服务端需支持Access-Control-Allow-Origin响应头 - 本地文件(
file://协议)直接打开也会触发污染,调试时请用本地服务器(如npx serve) -
toBlob()比toDataURL()更推荐,尤其导出大图时——前者不生成 base64 字符串,内存占用低得多
Canvas 的复杂性不在 API 多,而在状态管理:颜色、线宽、路径、变换矩阵、裁剪区域……全靠一个 ctx 对象维护。少一次 save()/restore(),就可能让下一段代码莫名其妙画歪。











