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

如何在带变换的CanvasRenderingContext2D中检测鼠标悬停元素

解决Canvas变换后的鼠标悬停检测问题

你可以利用Canvas的变换矩阵逆运算,直接将屏幕鼠标坐标转换为Canvas本地坐标系的坐标,这种方法能自动适配所有变换(平移、缩放、旋转等),比手动跟踪变换参数简洁得多。

核心逻辑

  1. 获取Canvas当前的变换矩阵,通过ctx.getTransform()实现;
  2. 对变换矩阵求逆,得到逆变换矩阵——这个矩阵可以把屏幕坐标“还原”为Canvas本地坐标系的坐标;
  3. 用逆矩阵转换鼠标的屏幕位置,之后就能直接在本地坐标系里计算鼠标与元素的距离。

修改后的代码

const ctx = canv.getContext('2d');
// 设置Canvas尺寸(示例值,可按需调整)
canv.width = 400;
canv.height = 300;

// 绘制背景
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canv.width, canv.height);

// 应用组合变换:平移到中心 + 缩放(演示适配性)
ctx.translate(canv.width / 2, canv.height / 2);
ctx.scale(2, 2);

// 绘制中心正方形(本地坐标(0,0)为中心)
ctx.fillStyle = 'yellow';
ctx.fillRect(-4, -4, 8, 8);

canv.addEventListener('mousemove', event => {
  // 1. 获取鼠标相对于Canvas的原始坐标
  const mouseScreenX = event.offsetX;
  const mouseScreenY = event.offsetY;

  // 2. 获取当前变换矩阵并求逆
  const transform = ctx.getTransform();
  const inverseTransform = transform.invertSelf();

  // 3. 用逆矩阵转换鼠标坐标到本地坐标系
  const mouseLocal = inverseTransform.transformPoint(new DOMPoint(mouseScreenX, mouseScreenY));

  // 4. 计算到元素中心(0,0)的距离
  const distance = Math.sqrt(mouseLocal.x ** 2 + mouseLocal.y ** 2);
  
  coord.innerText = `Distance to square: ${distance.toFixed(2)}`;
});
<canvas id="canv"></canvas>
<div id="coord"></div>

优势说明

  • 无需手动跟踪所有变换操作(比如多次平移、缩放叠加),矩阵运算会自动处理所有组合变换;
  • 代码逻辑通用,后续添加旋转(ctx.rotate())等其他变换时,无需修改鼠标检测部分的代码;
  • 计算结果精准,避免手动计算变换时可能出现的误差。

内容的提问来源于stack exchange,提问作者SteeveDroz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:42:57