La position de la souris à l'intérieur de autoscaled SVG
Je suis en train de vivre des préoccupations au sujet de la position du curseur de la souris à l'intérieur de mon document SVG. Je souhaiterais créer un potentiomètre qui suivra le curseur lorsque vous faites glisser, à l'aide de JavaScript dans une page HTML.
J'ai essayé evt.clientX/Y et evt.screenX/Y, mais comme mon SVG est dans autoscale, les coordonnées à l'intérieur de mon fichier SVG sont différents. J'ai été à la recherche d'une réponse pendant des jours maintenant, mais je ne pouvais pas trouver toute solution (que ce soit en sachant que mes SVG facteur de changement d'échelle en temps réel ou ont une fonction de souris emplacement en SVG système de coordonnées).
La rotation de suivre une règle simple:
if ( evt.screenX < xc)
ang = Math.atan( (evt.screenY - yc)/(evt.screenX - xc) )*360/(2*Math.PI) - 90;
if( evt.screenX > xc )
ang = Math.atan( (evt.screenY - yc)/(evt.screenX - xc) )*360/(2*Math.PI) + 90;
Avec (xc;yc) comme centre de rotation et le remplacement de tous les evt.screenX/Y par les coordonnées de la souris à l'intérieur de mon fichier SVG.
- vous devez travailler avec la matrice de transformation pour obtenir les coordonnées correctes. Un jsfiddle serait utile.
Vous devez vous connecter pour publier un commentaire.
Voir ce code, qui ne montre pas seulement comment transformer à partir de l'écran de l'espace mondial SVG de l'espace, mais aussi comment transformer un point de SVG de l'espace dans le transformé l'espace d'un élément:
http://phrogz.net/svg/drag_under_transformation.xhtml
En bref:
Modifier: j'ai créé un exemple adapté à vos besoins (quoique seulement en mondial SVG espace):
http://phrogz.net/svg/rotate-to-point-at-cursor.svg
Il ajoute la méthode suivante à la ci-dessus:
getScreenCTM()
méthode, de sorte qu'il peut être utilisé pour transformer l'événement de sourisclientX
etclientY
valeurs dans l'élément de coordonnées locales!document.rootElement
est la racine de l'élément SVG, pas besoin d'utiliserquerySelector
.createSVGPoint()
vous pouvez égalementsvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
@Phrogz: Merci pour votre merveilleux exemple et j'ai appris depuis que. J'ai changé certaines d'entre elles comme ci-dessous pour le rendre un peu facile la droite. Comme je pense que comme nous traitons les événements de la souris dans le noyau de java, nous pouvons également gérer même façon ici, donc j'ai essayé à ma façon dans votre exemple.
J'ai supprimé "rotateElement" la fonction que je pense que c'est quelque difficile et j'ai trouver une solution de remplacement s'il.
Voir code ci-dessous:
Donc ce que j'ai fait c'est que j'ai juste ajouté de l'écouteur seulement à un petit cercle et non l'ensemble des SVG et à chaque fois que lorsque la souris est déplacée par vous je vais obtenir
x, y
degetCursor()
fonction comme indiqué ci-dessus et je vais donner à cettex, y
commex2, y2
de ma ligne c'est qu'il ne se traduit pas et ne tourne pas. Vous devez déplacer votre souris pour au cercle, puis déplacez-le lentement et si votre souris laisser cercle puis ligne ne bougera pas tant que nous venons d'ajouter l'écouteur seulement sur un petit cercle à droite.Obtenir la bonne svg coordonnées de la souris est délicate. Tout d'abord, d'une façon courante est d'utiliser le clientX et clientY de l'événement à la propriété une soustraire à getBoundingClientRect() et clientLeft respectivement clientTop.
Mais, si le svg a un rembourrage informations de style supérieure à zéro, le système de coordonnées est le décalage. Donc, cette information doit être également soustraire:
Et pas aussi bien est en, que dans certains navigateurs la frontière propriété de changement de coordonnées, et dans d'autres pas. J'ai découvert, que le changement a lieu que si x et y de la propriété d'événement est pas disponibles.
Après cette transformation, les coordonnées x et y peut hors limite, qui devrait être corrigé. Mais que ne le pense.
Cette solution peut utiliser pour le clic, mousemove, mousedown, ... et ainsi de suite.
Vous pouvez accéder à une démonstration en direct ici: https://codepen.io/martinwantke/pen/xpGpZB