在没有鼠标移动事件的情况下跟踪鼠标的相对位置

Tracking relative mouse position without a mousemove event

本文关键字:鼠标 情况下 跟踪 相对 位置 事件 移动      更新时间:2023-09-26

我需要跟踪鼠标相对于应用程序中<canvas>元素的位置。目前,我在<canvas>上附加了一个mousemove事件侦听器,每当它启动时,它都会更新我的鼠标位置,在可用时使用offsetX/offsetY,在offsetX/Y不可用时使用layerX/layerY。使用offsetX/YlayerX/Y可以得到相对于<canvas>的鼠标坐标,这正是我想要的。随着我的应用程序发挥其魔力,各种CSS三维转换被应用于<canvas>,即使<canvas>经过了非常大的转换,offsetX/Y仍然在<canvas>的局部转换坐标空间中为我提供了准确的坐标。

这有点令人困惑,所以我试着举一个例子。如果我的<canvas>的宽度和高度都是100px,并且相对于浏览器视口位于(0,0),并且我单击(50,50)(在视口坐标中),这对应于<canvas>中的(50,50),50是通过offsetXoffsetY(正确)返回的值。如果我将transform: translate3d(20px,20px,0px)应用于我的<canvas>,并单击(50,50)(在视口坐标中),由于我的画布已向下移动了20像素,向右移动了20个像素,这实际上对应于相对于<canvas>的(30,30),30是通过offsetXoffsetY(正确)返回的值。

我面临的问题是,当用户没有实际移动鼠标,但<canvas>正在转换时,该怎么办。我只是在mousemove事件上更新鼠标的位置,那么当没有mousemove时该怎么办?

例如。我的鼠标位于(50,50),并且没有对<canvas>应用任何变换。我的this.mouseXthis.mouseY都等于50;当我将鼠标移动到(50,50)时,它们在最后的mousemove事件中被保存。在完全不移动鼠标的情况下,我将上述转换(transform: translate3d(20px,20px,0px))应用于我的<canvas>。现在,我需要this.mouseXthis.mouseY分别等于30,因为这是我的鼠标相对于<canvas>的当前变换的新位置。但CCD_ 37和CCD_。由于我从未移动过鼠标,因此没有触发mousemove事件,并且那些保存的coords也从未更新过。

我该怎么处理?我想过创建一个新的jQuery事件,根据我以前/以前的鼠标位置手动分配一些属性(pageXpageY?),然后触发该事件,但我不认为这会导致浏览器重新计算offsetXoffsetY属性。我也一直在考虑取已知的旧/以前的鼠标位置,并将其乘以我的变换矩阵,但这会变得非常复杂,因为我的鼠标坐标在二维空间中,但我应用于<canvas>的变换都是三维变换。

我想真的,我想做的是取我已知的二维页面位置,并将其光线投射到三维空间中,找出我在哪里找到转换后的<canvas>,所有这些都是javascript(jQuery可用)。

这可能吗?这有道理吗?

适用于所有浏览器

 var mouseX=0;
 var mouseY=0;
 var canvas = document.querySelector('#canvas');
 var rect = canvas.getBoundingClientRect();
 document.onmousemove = function(e) {
      mouseX=e.clientX-rect.left;
      mouseY=e.clientY-rect.top;
};
function updateCoords() {
      mouseX=e.clientX-mouseX;
      mouseY=e.clientY-mouseY;
      setTimeout(updatecoords,10);
}

现在我们可以调用updateCoords()函数一次,反复检查新位置。

 updateCoords();

你可以在updateCoords()函数中添加你的代码,它将每10毫秒执行一次

概念:mouseXmouseY变量在mousemove事件中更新,也在画布位置发生任何变化时更新。

即使不移动鼠标,看起来也要刷新鼠标位置值。你应该试试这样的东西:

var event = '';
var counter = 1;
$(function(e){
    event = e;
    window.setInterval(refresh, 10);
});
$(document).mousemove(function(e){
    event = e;
    refresh;
});
function refresh(){
    counter++;
    $('#mousepos').val("event.pageX: " + event.pageX + ", event.pageY: " + event.pageY + ", counter: " + counter)
}

计数器只是用于刷新的可视化。您可以将间隔设置为所需的一切(10=10ms=0.01s)。只需将.mousemove()事件中的所有内容移动到此refresh()函数中,并正确调用它,即使您不移动鼠标,您的鼠标位置也应该更新。

看看这把小提琴的生活例子:http://jsfiddle.net/82cmxw8L/1

编辑:

因为我的小提琴不适合询问者,我更新了它:http://jsfiddle.net/82cmxw8L/8/

新的是,鼠标位置现在每0.1秒设置一次,而不是只在鼠标移动时更新。