精确检测鼠标坐标

时间:2013-07-16 13:46:56

标签: javascript html5-canvas mouseevent

在一个昏昏欲睡的夜晚之后,我发现了this question的一些内容,我认为这基本上令人难以置信,至少在我看来。

鼠标坐标不精确(我想在运动发生时必须重新创建整个画布的高速处理),如上面的代码所示。我一块一块地测试了这段代码,发现问题不在我的循环中,而在于

的精度
if ((newMouseX !== mouseX) && (newMouseY !== mouseY)).

如果您通过较慢的时间测试这部分代码(这将允许您的眼睛在“停止”时检测坐标的差异,那么您将意识到newMouseX& mouseX已关闭90%的时间为1-2像素,9%的时间为> 2像素,仅相当于约1%的时间。(我没有测量统计数据,但这是我在几轮测试中选择的)

我无法在fiddle中使用它,但我认为您可以将其复制到测试场,看看我的意思。如果你可以让它在小提琴中工作,那将是很好的,所以专家可以给它一个简短的:)

这意味着鼠标被我的代码视为“移动”,即使它应该“停止”,因此在它们之间“停止”几次,因此在一秒钟内调用循环次数太多,这是我一直遇到的问题。

我很高兴听到其他专家的意见,包括那些能够测试并提出统计精确度/建议的人。

我的建议和目前的解决方案是在差异大于任一坐标的10个像素时考虑移动。当然这会带来一个问题,但我可以离开,直到出现一些更好的解决方案。

所以而不是

if ((newMouseX !== mouseX) && (newMouseY !== mouseY))

我用过

if (( Math.abs(newMouseX - mouseX) > 10) || ( Math.abs(newMouseY != mouseY) > 10) )

另一件需要考虑的事情是当它离开我的目标画布区域时如何处理鼠标位置...此刻看起来像一个无限的运动!

问题:

如何获得精确的鼠标坐标,以便我可以比较mouseX& newMouseX

感谢。

2 个答案:

答案 0 :(得分:2)

鼠标精度由硬件决定。例如,高精度鼠标将产生与内置鼠标垫不同的结果(更不用说触摸设备)。

但是,这不是您的代码和方案的问题。您只是在收听mousemove事件。根据定义,它只会在您移动鼠标时抛出一个事件 - 因此新鼠标位置永远不会与前一个位置相同。这是不可能的,应该100%关闭(除非你在检查之前触发两次+移动,最后一次回到第一位)。

通常,人们会听取mousedownmouseup事件以及他们不依赖鼠标移动来触发。在所有可能的情况下,根据鼠标移动检测开始和停止被认为是不可能的。

你可以做出妥协并定义一个开始是什么,停止是什么,即。如果鼠标在x毫秒后没有移动,则认为它是停止(开始是第一次移动)。

这意味着每次需要检测停止时都需要遵循此规则。进行绘图成像,有时你快速绘制其他时间。或者,如何在不绘制任何东西的情况下将鼠标移动到新位置......鼠标按钮的发明有充分的理由: - )

该规则很快就会被证明是无用的(或过于复杂,容易出现多个错误)。

对于画布外的鼠标位置,有几种方法可以解决这个问题。

您可以通过调用:

来获取画布边界
var canvasRect = canvas.getBoundingClientRect();

可让您properties检查鼠标位置何时在此矩形内部或外部。

另一种方法是收听canvas元素上的mouseleavemouseenter事件。

第三种是实际使用鼠标按钮。在canvas元素上按住鼠标按钮时,您需要设置一个标志,以便考虑mousemove个事件。

这将继续侦听,直到释放鼠标按钮。如果您在画布外部发布并使用画布mouseup事件,则无法检测到它。因此,您应该收听窗口mouseup事件,该事件将在任何一种情况下触发。

这也适用于mousemove个事件。使用窗口事件将允许您记录画布外的位置。如果您不想这样做,可以使用画布'mousemove,它将在画布边界处剪辑。

归结为:

组合使用mousedownmousemovemouseup事件,你会没事的。所有这些活动都会为鼠标位置提供clientXclientY

如果可以的话 - 你也可以去我的easyCanvas project进行测试并运行样本:
Sample - mouse event details

这将显示鼠标按下,移动和向上的详细信息(详细信息随其他信息一起扩展,但您至少可以验证鼠标位置 - 单击而不移动,您会看到鼠标位置完全相同)。

答案 1 :(得分:-1)

http://jsfiddle.net/6czap/74/

我希望我帮助了这个:)

$("div").mousemove(function(e){
   var pageCoords = "( " + e.pageX + ", " + e.pageY + " )";
  var clientCoords = "( " + e.clientX + ", " + e.clientY + " )";
  $("span:first").text("( e.pageX, e.pageY ) : " + pageCoords);
  $("span:last").text("( e.clientX, e.clientY ) : " + clientCoords);
});