0

After a sleepness night I discovered something about this question which I think is fundamentally mind boggling, at least to me.

Mouse coordinates ARE NOT PRECISE (I guess at a high speed of processing where the whole canvas has to be recreated when movement occurs) as in my codes above. I have tested this code piece by piece and discovered that the problem is not in my loop, but in the precision of

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

If you tested this part of code by slower times (which will allow your eyes to detect the difference in coordinates when 'it stops', then you will realise that newMouseX & mouseX are off by 1-2 pixel 90% of the time, > 2 pixel 9% of the time, and only equal about 1% of the time. (I did not measure the statistics but that is what I picked on several rounds of testing).

I can't get it to work in fiddle but I think you can copy it to your testing ground to see what I mean. If you can get it to work in fiddle it would be great so experts can give it a short :)

This means that the mouse is considered to be 'moving' by my code even when it should have 'stopped', and thus 'stops' several times in between, therefore calling the loop too many times in a second, which is the problem I have been having.

I would be happy to hear comments from other experts, including those who can test this and come up with a statistical precision/advice.

My advice, and solution for the moment, is to consider movement when the difference is more than 10 pixels of either coordinates. Of course this presents a problem, but I can leave with that until some better solution comes up.

so instead of

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

i have used

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

Another thing to consider is how to deal with the mouse position when it goes off my target canvas area... that looks like an infinite movement at the moment!

The Question:

How can I get the precise mouse coordinates so I can compare mouseX & newMouseX?

Thanks.

4

2 回答 2

2

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

但是,这不是您的代码和场景的问题。你只是在听mousemove事件。根据定义,它只会在您移动鼠标时引发事件 - 因此新的鼠标位置永远不会与前一个位置相同。那是不可能的,应该关闭 100%(除非你触发了两个以上的动作,在你检查之前最后一个回到拳头位置)。

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

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

这意味着您每次需要检测止损时都需要遵循此规则。成像进行绘图,有时您有时画得很慢,有时画得很快。或者,如何在不绘制任何内容的情况下将鼠标移动到新位置...发明鼠标按钮是有充分理由的:-)

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

至于画布外的鼠标位置,有几种方法可以处理这个问题。

您可以通过调用获取画布边界:

var canvasRect = canvas.getBoundingClientRect();

它为您提供了检查鼠标位置何时在此矩形内部或外部的属性。

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

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

这将一直收听,直到释放鼠标按钮。如果您将其释放到画布外并使用画布mouseup事件,则不会被检测到。因此,您应该收听在任何一种情况下都会触发的window事件mouseup

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

它归结为:

结合使用mousedown,mousemovemouseup事件,你会没事的。所有这些事件都为鼠标位置提供clientXclientY

如果可以的话 - 你也可以通过我的easyCanvas 项目进行测试并运行示例:
示例 - 鼠标事件详细信息

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

于 2013-07-16T14:39:16.797 回答
-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);
});
于 2013-07-16T14:01:02.050 回答