效果预览
具体实现
-
首先创建canvas元素,并添加鼠标事件
<canvas ref="canvasRef" :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px', }" @mousedown="($event) => handleMousedown($event)" @mousemove="($event) => handleMousemove($event)" @mouseup="handleMouseup()" @touchstart="($event) => handleMousedown($event)" @touchmove="($event) => handleMousemove($event)" @touchend=" handleMouseup(); mouseInCanvas = false; " @mouseleave=" handleMouseup(); mouseInCanvas = false; " @mouseenter="mouseInCanvas = true" @wheel="($event) => mousewheelListener($event)" ></canvas>
-
初始化画布
const initCanvas = () => { if (!canvasRef.value) return; ctx = canvasRef.value.getContext('2d'); if (!ctx) return; canvasRef.value.width = options.width; canvasRef.value.height = options.height; ctx.lineCap = 'round'; ctx.lineJoin = 'round'; }; -
处理鼠标移动事件
const handleMousedown = (e: MouseEvent | TouchEvent) => { const [mouseX, mouseY] = getMouseOffsetPosition(e); const x = mouseX / widthScale.value; const y = mouseY / heightScale.value; isMouseDown = true; lastPos = { x, y }; lastTime = new Date().getTime(); if (!(e instanceof MouseEvent)) { mouse.value = { x: mouseX, y: mouseY }; mouseInCanvas.value = true; } }; const handleMousemove = (e: MouseEvent | TouchEvent) => { const [mouseX, mouseY] = getMouseOffsetPosition(e); const x = mouseX / widthScale.value; const y = mouseY / heightScale.value; mouse.value = { x: mouseX, y: mouseY }; if (isMouseDown) handleMove(x, y); }; const handleMove = (x: number, y: number) => { const time = new Date().getTime(); if (options.model === 'pen') { const s = getDistance(x, y); const t = time - lastTime; const lineWidth = getLineWidth(s, t); draw(x, y, lineWidth); lastLineWidth = lineWidth; } else if (options.model === 'mark') draw(x, y, markSize.value); else erase(x, y); lastPos = { x, y }; lastTime = new Date().getTime(); }; const handleMouseup = () => { if (!isMouseDown) return; isMouseDown = false; }; -
绘制或清除笔迹
const draw = (posX: number, posY: number, lineWidth: number) => { if (!ctx) return; const lastPosX = lastPos.x; const lastPosY = lastPos.y; ctx.lineWidth = lineWidth; ctx.strokeStyle = options.color; ctx.beginPath(); ctx.moveTo(lastPosX, lastPosY); ctx.lineTo(posX, posY); ctx.stroke(); ctx.closePath(); }; -
清空画布及修改绘制或清除
const clearCanvas = () => { if (!ctx || !canvasRef.value) return; ctx.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height); }; const updateCtx = (model?: 'pen' | 'eraser' | 'mark') => { if (!ctx) return; if (model) { options.model = model; } if (options.model === 'mark') { ctx.globalCompositeOperation = 'xor'; ctx.globalAlpha = 0.5; } else if (options.model === 'pen') { ctx.globalCompositeOperation = 'source-over'; ctx.globalAlpha = 1; } };
完整代码 如果觉得文章对你有帮助,欢迎一键三连