canvas在线白板需精准处理坐标校准、状态管理与dpr适配,否则会出现线条断裂、偏移、模糊、卡顿及移动端失效等问题;必须用getboundingclientrect()换算真实坐标,正确调用beginpath()和moveto(),避免重复beginpath()导致重绘爆炸,移动端需preventdefault()并规范使用touch事件,清空画布须用clearrect()配合dpr缩放参数。

Canvas 做在线白板不是加个 <canvas></canvas> 标签再绑几个事件就完事——漏掉坐标校准、状态管理或 DPR 适配,画出来的线会断、偏、糊、卡,移动端直接失效。
mousedown 必须调 beginPath() 和 moveTo()
不调这两个,松开鼠标再点一下,线会从左上角(0, 0)“炸”出来;所有后续 lineTo() 都追加到上一条路径里,导致重绘爆炸、性能骤降。
-
beginPath()清空当前路径栈,开启新路径 -
moveTo(x, y)定起点,否则lineTo()默认从 (0, 0) 连过来 - 务必用
canvas.getBoundingClientRect()算真实坐标:e.clientX - rect.left,别用e.offsetX——它受 CSS transform、margin、缩放干扰,一动就偏
mousemove 里只 lineTo(),绝不能重复 beginPath()
每次移动都 beginPath(),等于把整条轨迹拆成无数独立短线:既断续,又让 stroke() 每帧重绘全部历史路径,画三笔就卡顿。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 保持一个开放路径,持续
lineTo(x, y)+stroke() - 只在
isDrawing === true时执行绘图逻辑 -
mouseup和mouseout都要设isDrawing = false,否则抬起后移出 canvas 还在画
移动端 touch 事件必须 preventDefault() 且取 touches[0]
不加 preventDefault(),手指一划页面就滚动,线条直接断开;用 changedTouches[0] 而非 touches[0],多指操作时坐标会乱跳。
- 监听
touchstart/touchmove/touchend,每个回调里都写e.preventDefault() - 坐标统一取
e.touches[0].clientX和e.touches[0].clientY - 同样过
getBoundingClientRect()换算,否则 iPhone 上画歪是常态
清空画布只能用 clearRect(),禁用 canvas.width = canvas.width
后者看着能清,实则重置整个 canvas 缓冲区:线宽、颜色、阴影、DPR 缩放状态全丢,高分屏下变模糊,CSS width:100% 场景还会拉伸变形。
- 正确写法:
ctx.clearRect(0, 0, canvas.width, canvas.height) - 若已做 DPR 适配(比如
canvas.width = rect.width * window.devicePixelRatio),clearRect()参数也得乘上devicePixelRatio - 硬写死像素值(如
clearRect(0,0,800,600))在缩放或响应式布局下必留白或裁剪
最易被忽略的是 DPR 与 getBoundingClientRect() 的配合——没这步,Retina 屏画线细、虚、抖,用户第一反应是“设备坏了”,而不是代码漏了适配。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










