Trouver la position de la souris par rapport à l'élément


244

Je veux faire une petite application de peinture en utilisant la toile. J'ai donc besoin de trouver la position de la souris sur la toile.


2
Solution complète: acko.net/blog/…
edA-qa mort-ora-y

3
J'adore sa brièveté, mais explique tout ce que ce post est.
dwjohnston

C'est vraiment vieux, mais je viens de démarrer un projet GitHub qui, entre autres, fait exactement ce dont vous avez besoin: brainlessdeveloper.com/mouse-move-interaction-spot-js
Fausto NA

Réponses:


177

Pour les personnes utilisant JQuery:

Parfois, lorsque vous avez des éléments imbriqués, l'un d'eux avec l'événement attaché, il peut être difficile de comprendre ce que votre navigateur considère comme le parent. Ici, vous pouvez spécifier quel parent.

Vous prenez la position de la souris, puis la soustrayez de la position de décalage de l'élément parent.

var x = evt.pageX - $('#element').offset().left;
var y = evt.pageY - $('#element').offset().top;

Si vous essayez d'obtenir la position de la souris sur une page dans un volet de défilement:

var x = (evt.pageX - $('#element').offset().left) + self.frame.scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + self.frame.scrollTop();

Ou la position par rapport à la page:

var x = (evt.pageX - $('#element').offset().left) + $(window).scrollLeft();
var y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();

Notez l'optimisation des performances suivante:

var offset = $('#element').offset();
// Then refer to 
var x = evt.pageX - offset.left;

De cette façon, JQuery n'a pas à rechercher #elementchaque ligne.

Mettre à jour

Il existe une nouvelle version uniquement JavaScript ci-dessous par @anytimecoder ci-dessous pour les navigateurs prenant en charge getBoundingClientRect () .


7
Cela at-il fonctionné pour vous @ben, j'apprécierais une "bonne réponse" ou un commentaire sur ce qui ne fonctionne toujours pas pour vous. Je peux peut-être vous aider davantage.
sparkyspider

8
Devrait éviter d'utiliser $ ('selector') dans un gestionnaire d'événements, sauf si vous voulez du code très lent. Présélectionnez votre élément et utilisez la référence présélectionnée dans votre gestionnaire. Même chose pour $ (window), faites-le une fois et mettez-le en cache.
Austin France

2
ce n'est pas une mention nécessaire: si vous copiez coller le code ci - dessus, n'oubliez pas de corriger var y = (evt.pageY - $('#element').offset().left) + $(window).scrollTop();àvar y = (evt.pageY - $('#element').offset().top) + $(window).scrollTop();
Raj Nathani

77
Comment cela pourrait-il être LA réponse puisque la question n'a rien à voir avec jQuery?
FlorianB

2
@Black mais certaines personnes demandent des choses en javascript au lieu de jquery car jquery peut ne pas être compatible dans leur environnement.
dbrree

307

Comme je n'ai pas trouvé de réponse sans jQuery que je pourrais copier / coller, voici la solution que j'ai utilisée:

function clickEvent(e) {
  // e = Mouse click event.
  var rect = e.target.getBoundingClientRect();
  var x = e.clientX - rect.left; //x position within the element.
  var y = e.clientY - rect.top;  //y position within the element.
}

JSFiddle d'un exemple complet


2
Vous devez arrondir le rectangle englobant pour garantir des valeurs entières avec cette méthode.
Jake Cobb

2
Une nouvelle modification devrait résoudre les problèmes de défilement (en utilisant clientX / Y)
Erik Koopmans

6
Cette réponse devrait être votée. Merci anytimecoder et @ErikKoopmans.
Ivan

3
PSA: le commentaire de @mpen est obsolète; cette méthode fonctionne, même dans les cas de défilement. Voir la version mise à jour de leur violon: jsfiddle.net/6wcsovp2
Xharlie

4
Je vous remercie! Une remarque: vous avez besoin e.currentTarget, pas e.target. Sinon, les éléments enfants l'affecteront
Maxim Georgievskiy

60

Ce qui suit calcule la relation de position de la souris avec l'élément canvas:

var example = document.getElementById('example'); 
example.onmousemove = function(e) { 
    var x = e.pageX - this.offsetLeft; 
    var y = e.pageY - this.offsetTop; 
}

Dans cet exemple, thisfait référence à l' exampleélément et ecorrespond à l' onmousemoveévénement.


83
C'est peut-être moi mais deux lignes de codes qui utilisent le mot-clé "this" manquent de contexte?
Deratrius

9
Manque vraiment de contexte. 'e' est l'événement et 'this' est l'élément auquel l'événement est lié var example = document.getElementById('example'); example.onmousemove = function(e) { var X = e.pageX - this.offsetLeft; var Y = e.pageY - this.offsetTop; }
Nick Bisby

22
Cela ne fonctionne pas si un élément descendant utilise un positionnement relatif ou absolu.
edA-qa mort-ora-y

12
Vous pouvez basculer thisvers e.currentTarget, cela vous donnera la position relative à l'élément auquel vous avez ajouté l'écouteur d'événements.
Linus Unnebäck

2
Cela semble donner la position relative à la partie visible de l'élément, pas à l'élément entier. Existe-t-il un moyen de gérer cela si une partie de l'élément ne peut pas être vue dans la fenêtre et qu'il y a des barres de défilement, etc.?
frabjous

37

Il n'y a pas de réponse en javascript pur qui renvoie des coordonnées relatives lorsque l'élément de référence est imbriqué à l'intérieur d'autres qui peuvent être avec un positionnement absolu. Voici une solution à ce scénario:

function getRelativeCoordinates (event, referenceElement) {

  const position = {
    x: event.pageX,
    y: event.pageY
  };

  const offset = {
    left: referenceElement.offsetLeft,
    top: referenceElement.offsetTop
  };

  let reference = referenceElement.offsetParent;

  while(reference){
    offset.left += reference.offsetLeft;
    offset.top += reference.offsetTop;
    reference = reference.offsetParent;
  }

  return { 
    x: position.x - offset.left,
    y: position.y - offset.top,
  }; 

}

3
Je ne pense pas que cela prenne en compte le htmldécalage d'élément
apieceofbart

3
Fonctionne très bien avec les conteneurs défilants, avec juste un petit changement: remplacez while(reference !== undefined)par while(reference). Dans Chrome au moins, le offsetParent ne finit pas par l'être undefined, mais null. Le referencesimple fait de vérifier si la vérité est vraie garantira que cela fonctionne avec les deux undefinedet null.
blex

Je donnerais un autre +1 si je le pouvais, en me faisant savoir qu'il y a une offsetParentpropriété, qui s'avère très utile dans d'autres situations!
FonzTech

En général, la vérification par rapport à undefined est généralement une mauvaise idée
Juan Mendes

Je pense que vous devez soustraire scrollLeftet scrollTopcompenser les descendants défilés.
Robert

20

Une bonne description de la difficulté de ce problème peut être trouvée ici: http://www.quirksmode.org/js/events_properties.html#position

En utilisant la technique qui y est décrite, vous pouvez trouver la position de la souris dans le document. Ensuite , vous vérifiez juste pour voir si elle se trouve dans la zone de délimitation de votre élément, que vous pouvez trouver en appelant element.getBoundingClientRect()qui retournera un objet avec les propriétés suivantes: { bottom, height, left, right, top, width }. À partir de là, il est trivial de savoir si le même événement s'est produit à l'intérieur de votre élément ou non.


1
Malheureusement, cela échoue s'il y a une sorte de rotation en cours
Eric

17

J'ai essayé toutes ces solutions et en raison de ma configuration spéciale avec un conteneur transformé en matrice (bibliothèque panzoom), aucune n'a fonctionné. Cela renvoie la valeur correcte, même en cas de zoom et de panoramique:

mouseevent(e) {
 const x = e.offsetX,
       y = e.offsetY
}

Mais seulement s'il n'y a aucun élément enfant sur le chemin. Cela peut être contourné en les rendant «invisibles» à l'événement, en utilisant CSS:

.child {
   pointer-events: none;
}

3
C'est certainement la façon de le faire en 2019. Les autres réponses sont toutes chargées de vieux bagages cruels.
Colin D du

1
@ColinD merci! J'ai oublié d'ajouter que cela fonctionne également dans IE11.
Fabian von Ellerts le

Cela a fonctionné pour moi. Cependant, je soupçonne que 1) peu de votes positifs 2) les réponses mieux notées sont beaucoup plus compliquées et 3) je ne vois aucun inconvénient expliqué. Quelqu'un connaît-il un inconvénient à utiliser cette approche?
Mark E

1
@MarkE Il n'y a rien de suspect à cela. C'est l'un des nombreux défauts de StackOverflow. Ces réponses que vous voyez en haut ont été publiées de nombreuses années avant cette réponse ici, elles ont donc gagné un élan énorme. Une fois qu'une réponse prend cet élan, il est assez difficile et assez rare de la battre.
Jack Giffin

9

Je suis tombé sur cette question, mais afin de le faire fonctionner pour mon cas (en utilisant le glisser sur un élément DOM (pas être un canevas dans mon cas)), j'ai trouvé que vous n'avez qu'à utiliser offsetXet offsetYsur l'événement dragover-mouse .

onDragOver(event){
 var x = event.offsetX;
 var y = event.offsetY;
}

2
cela a très bien fonctionné pour moi. pourquoi personne n'a voté pour cela? Je me demande s'il y a des pièges. Si j'en trouve, je ferai rapport!
bar

7
event.offsetX est relatif à l'élément sur lequel le pointeur de la souris se trouve actuellement, pas à l'élément auquel l'écouteur de survol est attaché. Si vous n'avez pas de structure d'élément imbriquée, c'est bien, mais si vous le faites, cela ne fonctionnera pas.
opsb

7

J'ai +1 'La réponse de Mark van Wyk car elle m'a mis dans la bonne direction, mais ne l'a pas tout à fait résolu pour moi. J'avais encore un décalage sur la peinture d'éléments contenus dans un autre élément.

Je l'ai résolu pour moi:

        x = e.pageX - this.offsetLeft - $(elem).offset().left;
        y = e.pageY - this.offsetTop - $(elem).offset().top;

En d'autres termes - j'ai simplement empilé tous les décalages de tous les éléments imbriqués


+1 pour vous! C'est la réponse que je cherchais. J'avais deux toiles empilées les unes sur les autres et les coordonnées étaient toutes fausses à cause des autres divs. Je savais que c'était le problème, mais je ne connaissais pas la logique / l'équation pour le compenser. Vous venez de résoudre mon problème aussi! = D merci!
Partack

5

Aucune des réponses ci-dessus n'est satisfaisante OMI, alors voici ce que j'utilise:

// Cross-browser AddEventListener
function ael(e, n, h){
    if( e.addEventListener ){
        e.addEventListener(n, h, true);
    }else{
        e.attachEvent('on'+n, h);
    }
}

var touch = 'ontouchstart' in document.documentElement; // true if touch device
var mx, my; // always has current mouse position IN WINDOW

if(touch){
    ael(document, 'touchmove', function(e){var ori=e;mx=ori.changedTouches[0].pageX;my=ori.changedTouches[0].pageY} );
}else{
    ael(document, 'mousemove', function(e){mx=e.clientX;my=e.clientY} );
}

// local mouse X,Y position in element
function showLocalPos(e){
    document.title = (mx - e.getBoundingClientRect().left)
        + 'x'
        + Math.round(my - e.getBoundingClientRect().top);
}

Et si jamais vous avez besoin de connaître la position de défilement Y actuelle de la page:

var yscroll = window.pageYOffset
        || (document.documentElement && document.documentElement.scrollTop)
        || document.body.scrollTop; // scroll Y position in page

4

Pour ceux d'entre vous qui développent des sites Web réguliers ou des PWA (Progressive Web Apps) pour les appareils mobiles et / ou les ordinateurs portables / moniteurs à écrans tactiles, vous avez atterri ici parce que vous pourriez être habitué aux événements de la souris et que vous êtes nouveau dans l'expérience parfois douloureuse de Touch événements ... ouais!

Il n'y a que 3 règles:

  1. Faites le moins possible pendant mousemoveou lors d' touchmoveévénements.
  2. Faites autant que possible pendant mousedownou lors d' touchstartévénements.
  3. Annulez la propagation et évitez les valeurs par défaut des événements tactiles pour empêcher les événements de souris de se déclencher également sur des appareils hybrides.

Inutile de dire que les touchévénements sont plus compliqués avec les événements car il peut y en avoir plusieurs et ils sont plus flexibles (compliqués) que les événements de souris. Je vais seulement couvrir une seule touche ici. Oui, je suis paresseux, mais c'est le type de contact le plus courant, donc là.

var posTop;
var posLeft;
function handleMouseDown(evt) {
  var e = evt || window.event; // Because Firefox, etc.
  posTop = e.target.offsetTop;
  posLeft = e.target.offsetLeft;
  e.target.style.background = "red";
  // The statement above would be better handled by CSS
  // but it's just an example of a generic visible indicator.
}
function handleMouseMove(evt) {
  var e = evt || window.event;
  var x = e.offsetX; // Wonderfully
  var y = e.offsetY; // Simple!
  e.target.innerHTML = "Mouse: " + x + ", " + y;
  if (posTop)
    e.target.innerHTML += "<br>" + (x + posLeft) + ", " + (y + posTop);
}
function handleMouseOut(evt) {
  var e = evt || window.event;
  e.target.innerHTML = "";
}
function handleMouseUp(evt) {
  var e = evt || window.event;
  e.target.style.background = "yellow";
}
function handleTouchStart(evt) {
  var e = evt || window.event;
  var rect = e.target.getBoundingClientRect();
  posTop = rect.top;
  posLeft = rect.left;
  e.target.style.background = "green";
  e.preventDefault(); // Unnecessary if using Vue.js
  e.stopPropagation(); // Same deal here
}
function handleTouchMove(evt) {
  var e = evt || window.event;
  var pageX = e.touches[0].clientX; // Touches are page-relative
  var pageY = e.touches[0].clientY; // not target-relative
  var x = pageX - posLeft;
  var y = pageY - posTop;
  e.target.innerHTML = "Touch: " + x + ", " + y;
  e.target.innerHTML += "<br>" + pageX + ", " + pageY;
  e.preventDefault();
  e.stopPropagation();
}
function handleTouchEnd(evt) {
  var e = evt || window.event;
  e.target.style.background = "yellow";
  // Yes, I'm being lazy and doing the same as mouseout here
  // but obviously you could do something different if needed.
  e.preventDefault();
  e.stopPropagation();
}
div {
  background: yellow;
  height: 100px;
  left: 50px;
  position: absolute;
  top: 80px;
  user-select: none; /* Disable text selection */
  -ms-user-select: none;
  width: 100px;
}
<div 
  onmousedown="handleMouseDown()" 
  onmousemove="handleMouseMove()"
  onmouseout="handleMouseOut()"
  onmouseup="handleMouseUp()" 
  ontouchstart="handleTouchStart()" 
  ontouchmove="handleTouchMove()" 
  ontouchend="handleTouchEnd()">
</div>
Move over box for coordinates relative to top left of box.<br>
Hold mouse down or touch to change color.<br>
Drag to turn on coordinates relative to top left of page.

Vous préférez utiliser Vue.js ? Je fais! Ensuite, votre code HTML ressemblerait à ceci:

<div @mousedown="handleMouseDown"
     @mousemove="handleMouseMove"
     @mouseup="handleMouseUp"
     @touchstart.stop.prevent="handleTouchStart"
     @touchmove.stop.prevent="handleTouchMove"
     @touchend.stop.prevent="handleTouchEnd">

3

vous pouvez l'obtenir par

var element = document.getElementById(canvasId);
element.onmousemove = function(e) {
    var xCoor = e.clientX;
    var yCoor = e.clientY;
}

Cela fonctionnera-t-il dans IE, ou IE utilise-t-il toujours window.event au lieu de passer l'événement au premier argument de l'écouteur? edit - Je suppose que IE n'a de toute façon pas l'élément canvas jusqu'à la version 9, mais cela devrait toujours prendre en charge IE à cause de choses comme les excanvas ....
Dagg Nabbit

21
Cela donnera les coordonnées par rapport à la fenêtre du navigateur, encore besoin de déterminer si elles sont dans l'élément en utilisant element.getBoundingClientRect ()
David W. Keith

merci de m'avoir informé de getBoundingClientRect !!!! Je n'ai jamais réalisé qu'il y avait une telle chose!
Gershom

@ DavidW.Keith commentaire devrait vraiment être considéré comme la bonne réponse!
Ulrik. S

3

Tiré de ce tutoriel , avec des corrections apportées grâce au commentaire du haut:

function getMousePos( canvas, evt ) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: Math.floor( ( evt.clientX - rect.left ) / ( rect.right - rect.left ) * canvas.width ),
        y: Math.floor( ( evt.clientY - rect.top ) / ( rect.bottom - rect.top ) * canvas.height )
    };
}

Utilisez sur une toile comme suit:

var canvas = document.getElementById( 'myCanvas' );
canvas.addEventListener( 'mousemove', function( evt ) {
    var mousePos = getMousePos( canvas, evt );
} );

3

Je me rends compte que je suis un peu en retard, mais cela fonctionne avec javascript PURE, et il vous donne même les coordonnées du pointeur dans l'élément si l'élément est plus grand que la fenêtre et que l'utilisateur a fait défiler.

var element_offset_x ; // The distance from the left side of the element to the left of the content area


....// some code here (function declaration or element lookup )



element_offset_x = element.getBoundingClientRect().left  -  document.getElementsByTagName("html")[0].getBoundingClientRect().left  ;

....// code here 




function mouseMoveEvent(event) 
{
   var pointer_location = (event.clientX + window.pageXOffset) - element_offset_x ; 
}

Comment ça fonctionne.

La première chose que nous faisons est d'obtenir l'emplacement de l'élément HTML (la zone de contenu) par rapport à la fenêtre courante. Si la page a des barres de défilement et est défilée, le nombre renvoyé par getBoundingClientRect().leftla balise html sera négatif. Nous utilisons ensuite ce nombre pour calculer la distance entre l'élément et la gauche de la zone de contenu. Avecelement_offset_x = element.getBoundingClientRect().left......;

Connaître la distance de l'élément par rapport à la zone de contenu. event.clientXnous donne la distance entre le pointeur et la fenêtre. Il est important de comprendre que la fenêtre et la zone de contenu sont deux entités différentes, la fenêtre peut se déplacer si la page défile. Par conséquent, clientX renverra le même numéro même si la page défile.

Pour compenser cela, nous devons ajouter la position x du pointeur (par rapport à la fenêtre), à ​​la position x de la fenêtre (par rapport à la zone de contenu). La position X de la fenêtre se trouve avec window.pageXOffset.


1
Merci d'être le seul répondeur à avoir pensé au défilement. Pensez à modifier votre réponse pour ajouter également l'axe des y.
frabjous

3

Basé sur la solution de @ Spider, ma version non JQuery est la suivante:

// Get the container element's bounding box
var sides = document.getElementById("container").getBoundingClientRect();

// Apply the mouse event listener
document.getElementById("canvas").onmousemove = (e) => {
  // Here 'self' is simply the current window's context
  var x = (e.clientX - sides.left) + self.pageXOffset;
  var y = (e.clientY - sides.top) + self.pageYOffset;
}

Cela fonctionne à la fois avec le défilement et le zoom (auquel cas, il renvoie parfois des flottants).


Je voterais positivement, mais cela ne devrait-il pas être un signe moins pour les décalages de page? Soit ça, soit les parenthèses autour de la deuxième partie?
Chris Sunami prend en charge Monica

1

Les coordonnées de la souris à l'intérieur d'un canevas peuvent être obtenues grâce à event.offsetX et event.offsetY. Voici un petit extrait pour prouver mon point:

c=document.getElementById("c");
ctx=c.getContext("2d");
ctx.fillStyle="black";
ctx.fillRect(0,0,100,100);
c.addEventListener("mousemove",function(mouseEvt){
  // the mouse's coordinates on the canvas are just below
  x=mouseEvt.offsetX;
  y=mouseEvt.offsetY;
  // the following lines draw a red square around the mouse to prove it
  ctx.fillStyle="black";
  ctx.fillRect(0,0,100,100);
  ctx.fillStyle="red";
  ctx.fillRect(x-5,y-5,10,10);
});
  
body {
  background-color: blue;
}

canvas {
  position: absolute;
  top: 50px;
  left: 100px;
}
<canvas id="c" width="100" height="100"></canvas>
    


Cela ne fonctionne pas si un autre div superpose la toile, tout comme @opsb l'a dit
David Peicho

1
canvas.onmousedown = function(e) {
    pos_left = e.pageX - e.currentTarget.offsetLeft;
    pos_top = e.pageY - e.currentTarget.offsetTop;
    console.log(pos_left, pos_top)
}

HTMLElement.offsetLeft

La HTMLElement.offsetLeftpropriété en lecture seule renvoie le nombre de pixels que le coin supérieur gauche de l'élément actuel est décalé vers la gauche dans le HTMLElement.offsetParentnœud.

Pour les éléments de type bloc, offsetTop, offsetLeft, offsetWidth, et offsetHeightdécrire la zone de bordure d'un élément par rapport à la offsetParent.

Cependant, pour les éléments de niveau en ligne (tels que span) qui peuvent passer d'une ligne à la suivante offsetTopet offsetLeftdécrire les positions de la première zone de bordure (à utiliser Element.getClientRects()pour obtenir sa largeur et sa hauteur), tandis que offsetWidthet offsetHeightdécrire les dimensions de la zone de bordure de délimitation (utiliser Element.getBoundingClientRect()pour obtenir sa position). Par conséquent, une boîte à la gauche, haut, largeur et la hauteur offsetLeft, offsetTop, offsetWidthet offsetHeightne sera pas une boîte de délimitation pour une période avec le texte enroulé.

HTMLElement.offsetTop

La HTMLElement.offsetToppropriété en lecture seule renvoie la distance de l'élément actuel par rapport au sommet du offsetParentnœud.

MouseEvent.pageX

La pageXpropriété en lecture seule renvoie la coordonnée X (horizontale) en pixels de l'événement par rapport à l'ensemble du document. Cette propriété prend en compte tout défilement horizontal de la page.

MouseEvent.pageY

La MouseEvent.pageYpropriété en lecture seule renvoie la coordonnée Y (verticale) en pixels de l'événement par rapport à l'ensemble du document. Cette propriété prend en compte tout défilement vertical de la page.

Pour plus d'explications, veuillez consulter le Mozilla Developer Network:

https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageX https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageY https: // developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop


Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question pour les lecteurs à l'avenir, et ces personnes pourraient ne pas connaître les raisons de votre suggestion de code.
Patrick Hund

J'espère vraiment que les lecteurs auront à l'avenir une API JS qui calculera cela pour eux. ;-) C'est probablement la réponse la plus simple, complète et autonome. Commenter le code auto-explicatif ne fait que distraire les déchets.
lama12345

J'appuie la demande d'explication de @ PatrickHund. Je ne suis pas un expert CSS / JS, et en savoir plus sur les relations entre, par exemple, pageet offsetserait très utile pour moi. Merci d'avoir considéré cette demande!
cxw

@cxw Ok, vous êtes maintenant le 2e downvote (eu 1 upvote) ... J'ai ajouté une longue explication maintenant, c'est comme 10x tant que les 4 lignes de code. Vous êtes les bienvenus, amusez-vous à lire. J'ai considéré votre demande! : p
lama12345

1
@cxw Je me suis amusé en ajoutant un élément positionné absolu supplémentaire et en forçant l'élément de toile lui-même hors écran, donc j'ai dû y faire défiler, comme gauche / haut 2000px hors écran. Impossible de casser ce code.
lama12345

1

J'ai implémenté une autre solution qui, je pense, est très simple, j'ai donc pensé partager avec vous.

Donc, le problème pour moi était que le div glissé sautait à 0,0 pour le curseur de la souris. J'ai donc dû capturer la position de la souris sur le div pour ajuster la nouvelle position du div.

J'ai lu les divs PageX et PageY et défini le haut et la gauche du en fonction de cela, puis pour obtenir les valeurs pour ajuster les coordonnées pour garder le curseur dans la position initiale dans le div, j'utilise un écouteur onDragStart et stocke le e.nativeEvent .layerX et e.nativeEvent.layerY qui seulement dans le déclencheur initial vous donne la position de la souris dans la div glissable.

Exemple de code:

 onDrag={(e) => {
          let newCoords;
          newCoords = { x: e.pageX - this.state.correctionX, y: e.pageY - this.state.correctionY };
          this.props.onDrag(newCoords, e, item.id);
        }}
        onDragStart={
          (e) => {
            this.setState({
              correctionX: e.nativeEvent.layerX,
              correctionY: e.nativeEvent.layerY,
            });
          }

J'espère que cela aidera quelqu'un qui a connu les mêmes problèmes que moi. :)


1
function myFunction(e) {
    var x =  e.clientX - e.currentTarget.offsetLeft ; 
    var y = e.clientY - e.currentTarget.offsetTop ;
}

cela fonctionne bien!


0

Vous devez connaître la structure de votre page, car si votre toile est un enfant d'un div qui est à son tour un enfant d'un autre div ... alors l'histoire devient plus compliquée. Voici mon code pour une toile qui est à l'intérieur de 2 niveaux de div s:

canvas.addEventListener("click", function(event) {
var x = event.pageX - (this.offsetLeft + this.parentElement.offsetLeft);
var y = event.pageY - (this.offsetTop + this.parentElement.offsetTop);
console.log("relative x=" + x, "relative y" + y);

});


0

La réponse originale a dit de le mettre dans un iframe. La meilleure solution consiste à utiliser les événements offsetX et offsetY sur un canevas dont le remplissage est défini sur 0px.

<html>
<body>
<script>

var main=document.createElement('canvas');
main.width="200";
main.height="300";
main.style="padding:0px;margin:30px;border:thick dashed red";
document.body.appendChild(main);

// adding event listener

main.addEventListener('mousemove',function(e){
    var ctx=e.target.getContext('2d');
    var c=Math.floor(Math.random()*0xFFFFFF);
    c=c.toString(16); for(;c.length<6;) c='0'+c;
    ctx.strokeStyle='#'+c;
    ctx.beginPath();
    ctx.arc(e.offsetX,e.offsetY,3,0,2*Math.PI);
    ctx.stroke();
    e.target.title=e.offsetX+' '+e.offsetY;
    });

// it worked! move mouse over window

</script>
</body>
</html>

0

Voici ce que j'ai.

    $(".some-class").click(function(e) {

    var posx = 0;
    var posy = 0;

    posx = e.pageX;
    posy = e.pageY;

    alert(posx);
    alert(posy);
});

0

Vous pouvez utiliser getBoudingClientRect()le relativeparent.

document.addEventListener("mousemove", (e) => {
  let xCoord = e.clientX - e.target.getBoundingClientRect().left + e.offsetX
  let yCoord = e.clientY - e.target.getBoundingClientRect().top + e.offsetY
  console.log("xCoord", xCoord, "yCoord", yCoord)
})
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.