Quelle est la façon la plus simple d'ajouter un gestionnaire d'événements click à un élément canvas qui renverra les coordonnées x et y du clic (par rapport à l'élément canvas)?
Aucune compatibilité de navigateur héritée requise, Safari, Opera et Firefox suffiront.
Réponses:
Edit 2018: Cette réponse est assez ancienne et utilise des vérifications pour les anciens navigateurs qui ne sont plus nécessaires, car les propriétés
clientX
etclientY
fonctionnent dans tous les navigateurs actuels. Vous voudrez peut-être consulter Patriques Answer pour une solution plus simple et plus récente.Réponse originale:
comme décrit dans un article que j'ai trouvé à l'époque mais qui n'existe plus:
A parfaitement fonctionné pour moi.
la source
Si vous aimez la simplicité mais que vous voulez toujours la fonctionnalité multi-navigateur, j'ai trouvé que cette solution fonctionnait le mieux pour moi. Ceci est une simplification de la solution de @ Aldekein mais sans jQuery .
la source
getBoundingClientRect
renvoie des positions par rapport au port de vue? Alors ma supposition était fausse. Je ne l'ai jamais testé car cela n'a jamais été un problème pour moi, et je voulais gentiment avertir les autres lecteurs d'un problème potentiel que j'ai vu, mais merci pour votre clarification.var canvas = document.getElementById('canvasID'); canvas.addEventListener("mousedown", function (e) { getCursorPosition(canvas, e);});
Mise à jour (5/5/16): la réponse de patriques devrait être utilisée à la place, car elle est à la fois plus simple et plus fiable.
Comme le canevas n'est pas toujours stylisé par rapport à la page entière, le
canvas.offsetLeft/Top
ne renvoie pas toujours ce dont vous avez besoin. Il renverra le nombre de pixels dont il est décalé par rapport à son élément offsetParent, qui peut être quelque chose comme undiv
élément contenant le canevas avec unposition: relative
style appliqué. Pour tenir compte de cela, vous devez parcourir la chaîne deoffsetParent
s, en commençant par l'élément canvas lui-même. Ce code fonctionne parfaitement pour moi, testé dans Firefox et Safari mais devrait fonctionner pour tous.La dernière ligne rend les choses pratiques pour obtenir les coordonnées de la souris par rapport à un élément canvas. Tout ce qui est nécessaire pour obtenir les coordonnées utiles est
la source
event.offsetX
etevent.offsetY
attributs, donc je modifie votre solution en ajoutantif (event.offsetX !== undefined && event.offsetY !== undefined) { return {x:event.offsetX, y:event.offsetY}; }
. on dirait que ça marche.event.offsetX
etevent.offsetY
fonctionne également dans IE9. Pour Firefox (testé avec v13), vous pouvez utiliserevent.layerX
etevent.layerY
.canvasX = event.pageX - totalOffsetX - document.body.scrollLeft; canvasY = event.pageY - totalOffsetY - document.body.scrollTop;
Le navigateur moderne gère maintenant cela pour vous. Chrome, IE9 et Firefox prennent en charge l'offsetX / Y comme ceci, en passant l'événement à partir du gestionnaire de clics.
La plupart des navigateurs modernes prennent également en charge layerX / Y, mais Chrome et IE utilisent layerX / Y pour le décalage absolu du clic sur la page, y compris la marge, le rembourrage, etc. Dans Firefox, layerX / Y et offsetX / Y sont équivalents, mais l'offset didn n'existe pas auparavant. Ainsi, pour la compatibilité avec les navigateurs légèrement plus anciens, vous pouvez utiliser:
la source
Selon le nouveau Quirksmode, les méthodes
clientX
etclientY
sont prises en charge dans tous les principaux navigateurs. Donc, c'est parti - le bon code qui fonctionne dans une div à défilement sur une page avec des barres de défilement:Cela nécessite également jQuery pour
$(canvas).offset()
.la source
J'ai fait une démonstration complète qui fonctionne dans chaque navigateur avec le code source complet de la solution de ce problème: Coordonnées d'un clic de souris sur Canvas en Javascript . Pour essayer la démo, copiez le code et collez-le dans un éditeur de texte. Enregistrez-le ensuite sous example.html et, enfin, ouvrez le fichier avec un navigateur.
la source
Voici une petite modification à la réponse de Ryan Artecona pour les toiles avec une largeur variable (%):
la source
Méfiez-vous lors de la conversion des coordonnées; plusieurs valeurs non inter-navigateurs sont renvoyées dans un événement de clic. Utiliser clientX et clientY seuls ne suffit pas si la fenêtre du navigateur est défilante (vérifiée dans Firefox 3.5 et Chrome 3.0).
Ce mode excentrique article en fournit une fonction plus correcte qui peut utiliser pageX ou pageY ou une combinaison de clientX avec document.body.scrollLeft et clientY avec document.body.scrollTop pour calculer la coordonnée de clic relative à l'origine du document.
MISE À JOUR: En outre, offsetLeft et offsetTop sont relatifs à la taille rembourrée de l'élément, pas à la taille intérieure. Un canevas avec le padding: style appliqué ne rapportera pas le coin supérieur gauche de sa région de contenu comme offsetLeft. Il existe différentes solutions à ce problème; le plus simple peut être d'effacer tous les styles de bordure, de remplissage, etc. sur la toile elle-même et de les appliquer à la place à une boîte contenant la toile.
la source
Je ne sais pas quel est le point de toutes ces réponses qui parcourent les éléments parents et font toutes sortes de choses étranges .
La
HTMLElement.getBoundingClientRect
méthode est conçue pour gérer la position réelle de l'écran de n'importe quel élément. Cela inclut le défilement, donc des trucs comme cescrollTop
n'est pas nécessaire:Image normale
L' approche la plus simple a déjà été publiée ici. C'est correct tant qu'aucun CSS sauvage règle n'est impliquée.
Manipulation de la toile / image étirée
Lorsque la largeur des pixels de l'image ne correspond pas à sa largeur CSS, vous devrez appliquer un certain rapport aux valeurs des pixels:
Tant que le canevas n'a pas de bordure, il fonctionne pour les images étirées (jsFiddle) .
Gestion des bordures CSS
Si la toile a une bordure épaisse, les choses se compliquent peu . Vous devrez littéralement soustraire la bordure du rectangle englobant. Cela peut être fait en utilisant .getComputedStyle . Cette réponse décrit le processus .
La fonction grandit alors un peu:
Je ne peux penser à rien qui pourrait brouiller cette fonction finale. Rendez-vous à JsFiddle .
Remarques
Si vous n'aimez pas modifier les
prototype
s natifs , changez simplement la fonction et appelez-la avec(canvas, event)
(et remplacez-lathis
parcanvas
).la source
Voici un très joli tutoriel-
http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
J'espère que cela t'aides!
la source
width
/height
surchargé mais reste l'une des meilleures solutions.En utilisant jQuery en 2016, pour obtenir des coordonnées de clic par rapport au canevas, je fais:
Cela fonctionne car les deux zones offset () et jqEvent.pageX / Y sont relatives au document, quelle que soit la position du défilement.
Notez que si votre canevas est mis à l'échelle, ces coordonnées ne sont pas les mêmes que les coordonnées logiques du canevas . Pour les obtenir, vous feriez également :
la source
C'est donc à la fois simple mais un sujet un peu plus compliqué qu'il n'y paraît.
Tout d'abord, il y a généralement des questions confondues ici
Comment obtenir des coordonnées de souris relatives à un élément
Comment obtenir les coordonnées de la souris pixel pixel pour l'API 2D Canvas ou WebGL
donc, réponses
Comment obtenir des coordonnées de souris relatives à un élément
Que l'élément soit ou non un canevas obtenant les coordonnées relatives de la souris de l'élément est le même pour tous les éléments.
Il y a 2 réponses simples à la question "Comment obtenir des coordonnées de souris relatives au canevas"
Réponse simple # 1 utilisez
offsetX
etoffsetY
Cette réponse fonctionne dans Chrome, Firefox et Safari. Contrairement à toutes les autres valeurs d'événement
offsetX
etoffsetY
prenez en compte les transformations CSS.Le plus gros problème avec
offsetX
et àoffsetY
partir de 2019/05, ils n'existent pas sur les événements tactiles et ne peuvent donc pas être utilisés avec iOS Safari. Ils existent sur les événements de pointeur qui existent dans Chrome et Firefox, mais pas dans Safari, mais apparemment Safari y travaille .Un autre problème est que les événements doivent être sur la toile elle-même. Si vous les placez sur un autre élément ou sur la fenêtre, vous ne pourrez plus choisir le canevas comme point de référence.
Réponse simple n ° 2 utilisation
clientX
,clientY
etcanvas.getBoundingClientRect
Si vous ne vous souciez pas des transformations CSS, la réponse la plus simple suivante consiste à appeler
canvas. getBoundingClientRect()
et à soustraire la gauche declientX
ettop
de la même manièreclientY
que dansCela fonctionnera tant qu'il n'y aura pas de transformations CSS. Il fonctionne également avec les événements tactiles et fonctionnera donc avec Safari iOS
Comment obtenir les coordonnées de la souris pixel pixel pour l'API 2D Canvas
Pour cela, nous devons prendre les valeurs ci-dessus et convertir la taille du canevas affichée en nombre de pixels dans le canevas lui-même
avec
canvas.getBoundingClientRect
etclientX
etclientY
ou avec
offsetX
etoffsetY
Remarque: Dans tous les cas, n'ajoutez pas de rembourrage ou de bordures au canevas. Cela compliquerait considérablement le code. Au lieu de cela, vous voulez qu'une bordure ou un rembourrage entoure le canevas dans un autre élément et ajoute le rembourrage et / ou la bordure à l'élément extérieur.
Exemple de travail utilisant
event.offsetX
,event.offsetY
Afficher l'extrait de code
Exemple de travail utilisant
canvas.getBoundingClientRect
etevent.clientX
etevent.clientY
Afficher l'extrait de code
la source
Je recommande ce lien - http://miloq.blogspot.in/2011/05/coordinates-mouse-click-canvas.html
la source
x = new Number()
? Le code ci-dessous qui réaffectex
ce qui signifie que le numéro attribué est immédiatement rejetéDans Prototype, utilisez cumulativeOffset () pour effectuer la sommation récursive comme mentionné par Ryan Artecona ci-dessus.
http://www.prototypejs.org/api/element/cumulativeoffset
la source
Vous pourriez simplement faire:
Cela vous donnera la position exacte du pointeur de la souris.
la source
Voir la démo sur http://jsbin.com/ApuJOSA/1/edit?html,output .
la source
Voici quelques modifications de la solution de Ryan Artecona ci-dessus.
la source
Tout d'abord, comme d'autres l'ont dit, vous avez besoin d'une fonction pour obtenir la position de l'élément canvas . Voici une méthode un peu plus élégante que certaines des autres sur cette page (à mon humble avis). Vous pouvez lui passer n'importe quel élément et obtenir sa position dans le document:
Calculez maintenant la position actuelle du curseur par rapport à celle-ci:
Notez que j'ai séparé la
findPos
fonction générique du code de gestion des événements. ( Comme il se doit . Nous devons essayer de limiter nos fonctions à une tâche chacune.)Les valeurs de
offsetLeft
etoffsetTop
sont relatives àoffsetParent
, ce qui pourrait être undiv
nœud wrapper (ou toute autre chose, d'ailleurs). Lorsqu'il n'y a pas d'élément enveloppant,canvas
ils sont relatifs àbody
, donc il n'y a pas de décalage à soustraire. C'est pourquoi nous devons déterminer la position de la toile avant de pouvoir faire autre chose.Similaire,
e.pageX
ete.pageY
donnez la position du curseur par rapport au document. C'est pourquoi nous soustrayons le décalage du canevas de ces valeurs pour arriver à la vraie position.Une alternative pour les éléments positionnés consiste à utiliser directement les valeurs de
e.layerX
ete.layerY
. C'est moins fiable que la méthode ci-dessus pour deux raisons:la source
ThreeJS r77
Après avoir essayé de nombreuses solutions. Cela a fonctionné pour moi. Pourrait aider quelqu'un d'autre à poster. Je l'ai d' ici
la source
Voici une solution simplifiée (cela ne fonctionne pas avec les bordures / défilement):
la source
Je créais une application ayant un canevas sur un pdf, qui impliquait beaucoup de redimensionnements du canevas comme Zoomer le pdf en avant et en arrière, et à mon tour à chaque zoom avant / arrière du PDF j'ai dû redimensionner le canevas pour adapter le taille du pdf, j'ai parcouru beaucoup de réponses dans stackOverflow, et je n'ai pas trouvé de solution parfaite qui finira par résoudre le problème.
J'utilisais rxjs et angular 6, et je n'ai trouvé aucune réponse spécifique à la dernière version.
Voici l'intégralité de l'extrait de code qui pourrait être utile à quiconque utilisant rxjs pour dessiner sur le dessus du canevas.
Et voici l'extrait qui corrige, les coordonnées de la souris par rapport à la taille du canevas, quelle que soit la façon dont vous zoomez / dézoomez le canevas.
la source
Hé, c'est dans le dojo, juste parce que c'est déjà ce que j'avais le code pour un projet.
Il devrait être assez évident de le reconvertir en JavaScript non dojo vanilla.
J'espère que cela pourra aider.
la source