必须调用 getcontext("2d") 才能绘图,因 canvas 元素本身无绘图能力,该方法返回实际绘图的上下文对象;漏调或错用 css 尺寸会导致图形不显示且不报错。

Canvas 绘图不是“写完就显示”,而是“获取上下文 → 设置状态 → 发出绘图命令 → 像素落定”这一整套手动控制流程;漏掉 getContext("2d") 或错用 CSS 控制尺寸,图形就根本不会按预期出现,且不报错。
为什么必须调用 getContext("2d") 才能画出东西
Canvas 元素本身只是个空容器,不带任何绘图能力。getContext("2d") 返回的 CanvasRenderingContext2D 对象才是实际执笔的“手”。没有它,fillRect()、stroke()、fillText() 全部静默失效——控制台不抛异常,也不渲染,容易误以为 JS 没执行或逻辑错了。
- 同一
<canvas></canvas>多次调用getContext("2d")会返回同一个对象,不是新建实例 - 不能混用上下文类型:已调过
"2d",再调"webgl"会返回null - 务必在 DOM 加载完成后再获取元素,否则
document.getElementById()返回null
width 和 height 必须写在 HTML 属性里,不是 CSS
CSS 的 width/height 只缩放画布的显示区域,不改变底层像素网格。结果是:坐标系错位、线条模糊、图形拉伸变形。比如你画一个 fillRect(0, 0, 100, 100),但用 CSS 把 canvas 拉到 200×200,它就会被拉成宽高各 200 的模糊正方形,而非清晰的 100×100 像素块。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- ✅ 正确:
<canvas id="cvs" width="400" height="300"></canvas> - ❌ 错误:
<canvas id="cvs" style="width:400px;height:300px"></canvas> - 响应式场景下,需用 JS 动态重设
canvas.width和canvas.height,再调ctx.scale(devicePixelRatio, devicePixelRatio)补偿高分屏
路径绘制前不调 beginPath() 会导致图形粘连
Canvas 的路径是累积的。如果画完一个圆没重置,接着画一条线,lineTo() 会从圆的终点开始连——折线图变乱线,饼图扇形连成一片,bug 很难肉眼发现。
- 每次绘制独立形状(如单个三角形、单个弧)前都应调
ctx.beginPath() -
fillRect()、strokeRect()是原子操作,不依赖路径,无需beginPath() - 画多边形时,
closePath()显式闭合比依赖自动闭合更可控 - 颜色/样式(
fillStyle、strokeStyle、lineWidth)必须在对应绘图命令前设置,否则本次绘制无效
Canvas 渲染本质是“位图+手动重绘”,不是 DOM 更新
Canvas 没有图层、没有自动 diff、没有事件绑定到图形上。它只是一块内存中的像素缓冲区,画完即固化。要动一个点,就得清掉相关区域再重画整个局部;要做动画,就得用 requestAnimationFrame 驱动循环:清屏 → 计算新状态 → 重绘。
- 高频刷新(如游戏、实时图表)正是 Canvas 的优势场景,性能远超 SVG/DOM
- 没有“修改某个矩形的颜色”这种操作,只有“擦掉旧的,画个新的”
- 设备像素比适配常被忽略:高分屏下 1px 线条默认变模糊,必须手动缩放像素网格并调
ctx.scale()
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










