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

时间:2014-09-24 00:22:44

标签: javascript css events css-transforms

我需要跟踪相对于应用中<canvas>元素的鼠标位置。目前,我有一个mousemove事件监听器附加到<canvas>,可以在发生时更新我的​​鼠标位置,使用offsetX / offsetY时可用,或layerXlayerY不可用时/ offsetX/Y。使用offsetX/YlayerX/Y可以获得相对于<canvas>的鼠标坐标,这正是我想要的。随着我的应用程序发挥其神奇作用,各种CSS 3d转换将应用于<canvas>,即使<canvas>已经过转换,offsetX/Y仍然可以在<canvas>内为我提供准确的坐标本地的,变换的坐标空间。

这令人困惑,所以我试着说一个例子。如果<canvas>的宽度和高度都是100px,并且相对于浏览器视口位于(0,0),我点击(50,50)(在视口坐标中),这对应于(50) ,50)在我的<canvas>中,50是通过offsetXoffsetY(正确)返回的值。如果我然后将transform: translate3d(20px,20px,0px)应用于我的<canvas>并点击(50,50)(在视口坐标中),因为我的画布已向下移动了20px,向右移动了20px,这实际上对应于(30 ,30)相对于<canvas>,而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>转换的新位置。但是this.mouseXthis.mouseY仍然等于50.因为我从未移动鼠标,所以没有触发mousemove事件,并且那些保存的坐标从未更新过。

我该如何处理?我考虑过创建一个新的jQuery事件,根据我之前/之前的鼠标位置手动分配一些属性(pageXpageY?),然后触发该事件,但我不认为这将导致浏览器重新计算offsetXoffsetY属性。我也一直在考虑使用已知的旧/先前鼠标位置并将其乘以我的变换矩阵,但由于我的鼠标坐标位于2d空间,因此我将变得非常复杂,但转换I&I #39; m应用于<canvas>都是3d变换。

我想真的,我想做的就是把我已知的2d页面位置和光线投射到3d空间中,找出我在javascript中遇到变换后的<canvas>的所有位置(jQuery是可用)。

这可能吗?这甚至有意义吗?

2 个答案:

答案 0 :(得分:1)

适用于所有浏览器

 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事件中更新,并且在画布位置发生任何变化时也会更新。

答案 1 :(得分:0)

即使您不移动鼠标,您也希望刷新鼠标位置值。你应该尝试这样的事情:

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秒设置一次,不管是什么,而不是仅在鼠标移动时更新。