2015-03-25 6 views
10

Ich konnte die Klickkoordinaten (x und y) relativ zu dem Element, das das Ereignis auslöst, nicht berechnen. Ich habe kein einfaches Beispiel online gefunden.Wie erhalten Sie die Klick-Koordinaten relativ zum SVG-Element, das den OnClick-Listener enthält?

Ich habe eine einfache svg (mit 100px linken Rand) in einer HTML-Seite. Es enthält eine group (übersetzte 30px 30px), die einen onclick Listener angeschlossen hat. Und innerhalb dieser group habe ich eine rect mit 50px Breite und Höhe.

Nachdem ich auf einen Teil des Elements group geklickt habe, erhalte ich ein Ereignisobjekt mit Koordinaten relativ zur HTML-Seite (evt.clientX und evt.clientY).

Was ich wissen muss ist, wo genau der Benutzer in das group Element geklickt hat (das Element, das den onclick Listener hält).

Wie konvertiere ich clientX und clientY Koordinaten in die group Elementkoordinaten. Also sag, wenn ich auf den oberen linken Teil des rect klicke, sollte es mir x = 0 und y = 0 geben. Hier

ist derzeit, was ich habe:

<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
     <style> 
 
      body{ 
 
       background:black; 
 
      } 
 
      svg{ 
 
       fill:white; 
 
       background:white; 
 
       position: absolute; 
 
       top:100px; 
 
       left:100px; 
 
      } 
 
      
 
     </style> 
 
     <script> 
 
      function clicked(evt){ 
 
       alert("x: "+evt.clientX+" y:"+evt.clientY); 
 
      } 
 
     </script> 
 
    </head> 
 
    <body> 
 
     <div> 
 
      <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"> 
 
       <g transform="translate(30 30)" onclick="clicked(evt)"> 
 
        <rect x="0" y="0" width="50" height="50" fill="red"/> 
 
       </g> 
 
      </svg>  
 
     </div> 
 
    </body> 
 
</html>

Antwort

19

Try getBoundingClientRect() zu verwenden: http://jsfiddle.net/fLo4uatw/

function clicked(evt){ 
    var e = evt.target; 
    var dim = e.getBoundingClientRect(); 
    var x = evt.clientX - dim.left; 
    var y = evt.clientY - dim.top; 
    alert("x: "+x+" y:"+y); 
} 
+0

Beachten Sie, dass dieses Skript nicht funktioniert, wenn Ihre ViewBox von der Standardansicht abweicht ('viewBox =" 0 0 width height "'). Ich habe eine alternative Antwort gepostet, die mit jeder ViewBox funktioniert. –

18

Tolokoban-Lösung hat die Einschränkung, dass es nicht, wenn nicht funktioniert Ihre viewBox weicht vom Standardwert ab, wenn es sich von viewBox="0 0 width height" unterscheidet . Eine bessere Lösung, die auch viewBox berücksichtigt, ist dies:

var pt = svg.createSVGPoint(); // Created once for document 

function alert_coords(evt) { 
    pt.x = evt.clientX; 
    pt.y = evt.clientY; 

    // The cursor point, translated into svg coordinates 
    var cursorpt = pt.matrixTransform(svg.getScreenCTM().inverse()); 
    console.log("(" + cursorpt.x + ", " + cursorpt.y + ")"); 
} 

(Kredit geht an Smerk, der posted the code)

Wenn die viewBox ist nicht auf den Standardwert eingestellt oder gesetzt ist, wird dieses Skript die gleiche Rück Werte wie Tolokobans Skript. Aber wenn Sie ein SVG wie <svg width="100px" height="100" viewBox="0 0 200 200"> haben, wird nur diese Version Ihnen die richtigen Ergebnisse geben.

+1

Was Alexander gesagt hat, ist vollkommen richtig! Meine Lösung war spezifisch für das gepostete Beispiel, in dem Sie ein Standard-ViewPort sind. – Tolokoban

+1

Beachten Sie, dass 'svg' eine Referenz auf das Element svg ist. Wenn Sie react verwenden, können Sie die Referenz erhalten, indem Sie eine "ref = {(ref) => this.svg = ref}' prop hinzufügen. –

+0

Das ist Magie! Wie sieht es mit der Browser-Unterstützung aus? – Merigold

Verwandte Themen