2013-07-16 7 views
0

Après une nuit de sommeil, j'ai découvert quelque chose à propos de this question qui, selon moi, est fondamentalement ahurissant, du moins pour moi.Détecter les coordonnées de la souris avec précision

Coordonnées de la souris NE SONT PAS PRÉCIS (Je suppose à une grande vitesse de traitement où toute la toile doit être recréée lorsque le mouvement se produit) comme dans mes codes ci-dessus. Je l'ai testé ce morceau de code par pièce et a découvert que le problème est pas dans ma boucle, mais la précision des

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

Si vous avez testé cette partie du code en temps plus lent (ce qui permettra à vos yeux détecter la différence de coordonnées quand «il s'arrête», alors vous vous rendrez compte que newMouseX & mouseX sont désactivés par 1-2 pixel 90% du temps,> 2 pixels 9% du temps, et seulement égal à environ 1% du temps . (Je n'ai pas mesuré les statistiques mais c'est ce que j'ai choisi sur plusieurs séries de tests)

Je ne peux pas l'obtenir t o travailler en fiddle mais je pense que vous pouvez le copier sur votre terrain d'essai pour voir ce que je veux dire. Si vous pouvez le faire travailler en fiddle, ce serait génial, donc les experts peuvent le donner en raccourci :)

Cela signifie que la souris est considérée comme étant 'en mouvement' par mon code même si elle devrait être 'arrêtée' , et donc 's'arrête' plusieurs fois entre les deux, appelant ainsi la boucle trop de fois en une seconde, ce qui est le problème que j'ai eu.

Je serais heureux d'entendre les commentaires d'autres experts, y compris ceux qui peuvent tester cela et proposer une précision statistique/conseils.

Mon conseil, et la solution pour le moment, est de considérer le mouvement lorsque la différence est supérieure à 10 pixels de l'une ou l'autre des coordonnées. Bien sûr, cela pose un problème, mais je peux partir avec ça jusqu'à ce qu'une meilleure solution apparaisse.

donc au lieu de

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

j'ai utilisé

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

Une autre chose à considérer est de savoir comment faire face à la position de la souris quand il va de ma zone de toile cible ... qui ressemble un mouvement infini en ce moment!

La question:

Comment puis-je obtenir les coordonnées, je peux comparer la souris afin précise mouseX & newMouseX?

Merci.

+0

Je ne pense pas que votre code ait beaucoup de sens. Vous avez un écouteur d'événement ** mousemove **. Par définition, cet événement se déclenchera * lorsque la souris se déplace *. Si la souris n'a pas bougé, le gestionnaire d'événements ne se déclenchera pas. – Pointy

+1

Working Fiddle: http://jsfiddle.net/3vEqj/1/ – Ford

Répondre

2

Souris précision est déterminée par le matériel. Une souris de haute précision produira des résultats différents d'un tapis de souris intégré par exemple (sans parler des périphériques tactiles).

Cependant, ce n'est pas le problème avec votre code et votre scénario. Vous écoutez seulement l'événement mousemove. Par définition, il ne lancera un événement que lorsque vous bougerez la souris. Ainsi, la nouvelle position de la souris ne pourra jamais être à la même position que la précédente. Ce serait impossible et devrait être désactivé de 100% (sauf si vous déclenchez deux mouvements + où le dernier revient à la première position avant de vérifier).

Normalement, on écoute les événements ainsi mousedown et mouseup car ils ne dépendent pas d'une souris déplacer pour déclencher. La détection du démarrage et de l'arrêt uniquement en fonction du mouvement de la souris est considérée comme impossible dans toutes les circonstances possibles.

Vous pouvez faire un compromis et faire une définition de ce qu'est un début et ce qu'est un arrêt, c'est-à-dire. Si la souris n'a pas bougé après x millisecondes, cela est considéré comme un arrêt (le début serait au premier mouvement). Cela signifie que vous devrez suivre cette règle chaque fois que vous aurez besoin de détecter un arrêt. Imaging faire un dessin et parfois vous dessinez parfois lente d'autres fois rapidement. Ou, comment déplacer la souris à une nouvelle position sans rien dessiner ... Il y a une bonne raison d'inventer le bouton de la souris :-)

La règle va bientôt s'avérer inutile (ou trop compliqué sujet à plus d'une erreur). En ce qui concerne les positions de la souris à l'extérieur du canevas, il existe plusieurs façons de gérer cela.

Vous pouvez obtenir les limites de toile en appelant:

var canvasRect = canvas.getBoundingClientRect(); 

qui vous donne properties vérifier lorsque la position de la souris est à l'intérieur ou à l'extérieur de ce rectangle.

Une autre méthode consiste à écouter les événements mouseleave et mouseenter sur l'élément canvas.

Un troisième est d'utiliser réellement les boutons de la souris. Lorsque le bouton de la souris est maintenu enfoncé sur l'élément canvas, vous définissez un drapeau afin que les événements mousemove soient pris en compte.

Ceci continuera à écouter jusqu'à ce que le bouton de la souris soit relâché. Si vous le libérez en dehors du canevas et que vous utilisez l'événement canvas mouseup, il ne sera pas détecté. Pour cela, vous devriez écouter l'événement de la fenêtre qui se déclenchera dans les deux cas. Ceci s'applique également aux événements mousemove. L'utilisation de l'événement window vous permettra d'enregistrer des positions en dehors du canevas. Si vous ne voulez pas faire cela, vous pouvez utiliser canvas 'mousemove qui va couper les limites de la toile.

Il se résume à:

Utilisez les mousedown, mousemove et mouseup événements en combinaison et vous serez bien. Tous ces événements fournit clientX et clientY pour les positions de la souris.

Et si je - vous pouvez également tester en allant à mon easyCanvas project et exécuter l'exemple:
Sample - mouse event details

Cela vous montrera les détails de la souris vers le bas, se déplacer et vers le haut (les détails sont étendus à d'autres informations , mais vous pouvez au moins vérifier les positions de la souris - faites un clic sans bouger et vous verrez que la position de la souris est exactement la même).

+0

Merci à vous tous ci-dessus. En regardant maintenant - vous avez beaucoup de sens. Je vais revenir une fois que je l'ai réécrit à mes exigences. –

+0

J'essayais d'employer [cette technique] (http://www.rgraph.net/blog/2013/february/an-example-of-the-html5-canvas-ispointinpath-function.html), mais j'ai un beaucoup plus de formes 1000+, c'est pourquoi je veux que le redraw se produise seulement quand la souris arrête, sans un événement de bouton, pas quand il bouge ... –

+1

@HanningtonMambo avec autant de formes que vous aurez besoin pour isoler la zone que vous test par f.ex. ajouter un rectangle de délimitation à la forme à la création (voir quad-tree). Ensuite, vous vérifiez les coordonnées et seules les formes avec un rectangle contenant la position x/y seront vérifiées avec isPointInPath. Si vous avez de nombreuses formes qui se chevauchent, incluez également la priorité en utilisant un tableau que vous vérifiez de bout en bout. Mais je crois que cela dépasse la portée de la question initiale. Je vous suggérerais up-vote/accepter les réponses à la question si quelqu'un a aidé avec le problème et en ouvrir un nouveau spécifique pour ce nouveau problème. – K3N

-1

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

J'espère que j'ai aidé avec ce :)

$("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); 
}); 
+0

Il n'utilise pas jQuery, et cela n'a vraiment rien à voir avec la question. – Pointy

Questions connexes