html5 canvas涂鸦画板核心是正确处理鼠标事件、坐标转换和绘图状态:mousedown设isdrawing=true并调beginpath()/moveto(),mousemove中仅当isdrawing为真时lineto()/stroke(),mouseup/mouseout均置isdrawing=false;用getboundingclientrect()校正坐标;linewidth与linecap="round"提升手感;清空用clearrect()而非重设width。

用 HTML5 Canvas 实现简单涂鸦画板,核心是正确处理鼠标事件、坐标转换和绘图状态。关键不在代码行数多寡,而在于几个容易出错的细节是否到位。
监听三个基础事件并管理绘制状态
必须绑定 mousedown、mousemove 和 mouseup(或 mouseout)事件,并用一个布尔变量(如 isDrawing)标记当前是否处于落笔状态:
- 在
mousedown中设isDrawing = true,调用ctx.beginPath(),再用ctx.moveTo(x, y)记下起点 - 在
mousemove中只当isDrawing为true时才执行ctx.lineTo(x, y)和ctx.stroke() -
mouseup和mouseout都要设isDrawing = false,避免鼠标移出后松开再移入继续画线
准确获取鼠标在画布内的真实坐标
直接读 event.clientX / clientY 得到的是页面坐标,不是画布坐标。若画布有边距、缩放或滚动,会严重偏移:
- 每次计算前先调用
const rect = canvas.getBoundingClientRect() - 然后用
const x = e.clientX - rect.left和const y = e.clientY - rect.top换算 - 不要在 mousemove 里反复调用 getBoundingClientRect(),性能敏感,只需在 mousedown 或初始化时缓存一次 rect 即可
设置合适的笔触样式提升涂鸦感
线宽和端点样式对手感影响极大,不能只靠默认值:
-
ctx.lineWidth建议从 4~6 开始试;太细(如 1)易断,太粗(如 20)难控制 -
ctx.lineCap = "round"让每一段线头变圆,拼接更顺滑,消除“锯齿感” -
ctx.lineJoin = "round"同样让拐角处圆润,适合手绘风格 - 所有样式(颜色、粗细)应在
beginPath()之前设置,否则可能影响上一条路径
安全清空画布,别用重设 width/height
canvas.width = canvas.width 看似能清空,但会重置整个缓冲区,破坏 CSS 缩放、高 DPR 适配,甚至导致画面拉伸:
- 正确做法是
ctx.clearRect(0, 0, canvas.width, canvas.height) - 如果需要保留背景色,紧接着加
ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height) - 高分辨率屏(如 Retina)需额外做设备像素比(DPR)适配,否则 clearRect 可能漏像素
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











