vue 3 中用 canvas 实现图形绘制需绑定鼠标/触摸事件并用 getboundingclientrect() 校准坐标,通过 currentmode 切换自由绘制、矩形拖拽或清空模式,mousemove 前 clearrect 再重绘历史图形+临时图形以避免闪烁。

在 Vue 3 中用 Canvas 实现图形绘制,核心是把鼠标事件(mousedown、mousemove、mouseup)与 Canvas 2D 绘图上下文(ctx)联动起来,再配合响应式状态控制绘制流程。不需要第三方库,原生 Canvas API 就够用。
绑定事件并获取准确坐标
Canvas 坐标容易受缩放、滚动或父容器 padding 影响,直接用 clientX/clientY 会偏移。推荐用 getBoundingClientRect() 计算相对画布左上角的位置:
- 在
setup()中用ref持有 canvas 元素和 ctx - 监听
@mousedown时调用getMousePos(event)获取起始点 - 该函数返回
{ x: event.clientX - rect.left, y: event.clientY - rect.top }
区分绘制模式:自由线 vs 矩形框
同一套事件可支持多种图形,靠 currentMode(如 'pen'、'rect'、'clear')切换逻辑:
-
自由绘制(画笔):按下时
beginPath()+moveTo(),移动时lineTo()+stroke() -
拖拽矩形:按下记下起点
(startX, startY),移动时实时计算宽高,用strokeRect(startX, startY, width, height)绘制临时框;松开后存入历史数组并重绘全部 -
清空画布:直接调用
ctx.clearRect(0, 0, canvas.width, canvas.height)
避免重复绘制与闪烁的关键操作
鼠标移动频繁触发,若每次都全量重绘,会出现抖动或残留。稳妥做法是:
- 每次
mousemove前先clearRect()清空画布 - 紧接着重绘所有已保存的图形(比如历史矩形列表
totalRect) - 最后叠加当前正在拖拽的临时图形(如未松开的矩形边框)
- 不依赖
requestAnimationFrame也能流畅,前提是清除+重绘逻辑轻量
移动端需额外处理触摸事件
如果目标包含手机端,不能只监听鼠标事件。要同时绑定:
-
@touchstart.prevent→ 替代mousedown,取touches[0] -
@touchmove.prevent→ 替代mousemove,注意preventDefault()阻止页面滚动 -
@touchend→ 替代mouseup - 触摸坐标同样需通过
getBoundingClientRect()校准,不可直接用pageX
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











