You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于鼠标移动速度调整绘图标记大小的JavaScript实现

实现思路与完整代码

当然可以使用deltaX(以及deltaY)来实现需求,mousemove事件自带的deltaX/deltaY就是鼠标相对于上一次移动事件的偏移量,无需手动记录上一位置,能简化代码逻辑。以下是具体实现:

关键逻辑说明

  1. 速度计算:通过deltaX/deltaY计算移动距离,结合两次移动的时间差得到移动速度(像素/毫秒)。
  2. 大小映射:将速度值映射到合理的标记尺寸范围,避免极端大小影响体验。
  3. 坐标校正:使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 01:35:21