基于鼠标移动速度调整绘图标记大小的JavaScript实现
实现思路与完整代码
当然可以使用deltaX(以及deltaY)来实现需求,mousemove事件自带的deltaX/deltaY就是鼠标相对于上一次移动事件的偏移量,无需手动记录上一位置,能简化代码逻辑。以下是具体实现:
关键逻辑说明
- 速度计算:通过
deltaX/deltaY计算移动距离,结合两次移动的时间差得到移动速度(像素/毫秒)。 - 大小映射:将速度值映射到合理的标记尺寸范围,避免极端大小影响体验。
- 坐标校正:使用
offsetX/offsetY获取相对于Canvas的坐标,避免文档坐标导致的绘制错位。
完整修改代码
class App { constructor() { this.container = this.createContainer(); this.canvas = this.createCanvas(); this.ctx = this.canvas.getContext("2d"); this.addEventListeners(); this.isDrawing = false; this.lastMoveTime = Date.now(); // 记录上一次移动的时间戳 } createContainer = () => { const container = document.createElement("div"); container.className = "app-container"; container.style.width = "100vw"; container.style.height = "100vh"; container.style.position = "relative"; container.style.margin = 0; container.style.padding = 0; document.body.appendChild(container); // 重置body默认样式避免滚动条 document.body.style.margin = 0; document.body.style.padding = 0; return container; }; createCanvas = () => { const canvas = document.createElement("canvas"); canvas.className = "app-canvas"; canvas.style.position = "absolute"; canvas.style.top = 0; canvas.style.left = 0; canvas.style.cursor = "crosshair"; this.container.appendChild(canvas); canvas.width = this.container.offsetWidth; canvas.height = this.container.offsetHeight; return canvas; }; addEventListeners = () => { this.canvas.addEventListener("mousemove", this.onMouseMove); this.canvas.addEventListener("mousedown", this.onMouseDown); document.addEventListener("mouseup", this.onMouseUp); // 监听窗口 resize,保持Canvas尺寸匹配容器 window.addEventListener("resize", () => { this.canvas.width = this.container.offsetWidth; this.canvas.height = this.container.offsetHeight; }); }; onMouseDown = () => { this.isDrawing = true; this.lastMoveTime = Date.now(); // 开始绘制时重置时间戳 }; onMouseMove = (event) => { if (!this.isDrawing) return; const now = Date.now(); const timeDelta = now - this.lastMoveTime; if (timeDelta === 0) return; // 避免除以0错误 // 用deltaX和deltaY计算二维移动距离 const distance = Math.sqrt(Math.pow(event.deltaX, 2) + Math.pow(event.deltaY, 2)); // 计算移动速度(像素/毫秒) const speed = distance / timeDelta; // 映射速度到标记大小,限制最小/最大值 const minSize = 2; const maxSize = 20; // 调整系数(60)可改变大小随速度变化的敏感度 const size = Math.min(maxSize, Math.max(minSize, speed * 60 + minSize)); // 使用相对于Canvas的坐标绘制 this.drawBall(event.offsetX, event.offsetY, size); this.lastMoveTime = now; }; onMouseUp = () => { this.isDrawing = false; }; drawBall = (x, y, size = 5) => { this.ctx.beginPath(); this.ctx.arc(x, y, size, 0, Math.PI * 2); this.ctx.fillStyle = "#6f0ecf"; this.ctx.fill(); this.ctx.closePath(); }; } export { App };
可调整参数说明
minSize/maxSize:控制标记的最小/最大尺寸,可根据需求修改。speed * 60中的60:调整大小随速度变化的敏感度,数值越大,相同速度下标记越大。
内容的提问来源于stack exchange,提问作者Erin
相关产品推荐
相关产品推荐

