No he podido calcular las coordenadas de clic (x e y) en relación con el elemento que desencadena el evento. No he encontrado un ejemplo fácil en línea.
Tengo un svg simple (con un margen izquierdo de 100 px) en una página HTML. Contiene un group (traducido 30px 30px) que tiene un oyente onclick adjunto. Y dentro de ese group tengo un rect con 50px de ancho y alto.
Después de hacer clic en cualquier parte del elemento del group , obtengo un objeto de evento con coordenadas relativas a la página HTML ( evt.clientX y evt.clientY ).
Lo que necesito saber es dónde hizo clic exactamente el usuario dentro del elemento del group (el elemento que contiene el oyente onclick).
¿Cómo convierto las coordenadas de clientX y clientY en las coordenadas del elemento de group ? Por ejemplo, si hago clic en la parte superior izquierda del rect , debería darme x=0 y y=0.
Esto es lo que tengo actualmente:
<!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>La solución de Tolokoban tiene la limitación de que no funciona si su viewBox se desvía del valor predeterminado, es decir, si es diferente de viewBox="0 0 width height" . Una mejor solución que también tiene en cuenta viewBox es esta:
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 + ")"); }(El crédito es para Smerk, quien publicó el código )
Si viewBox no está configurado o está configurado de forma predeterminada, este script devolverá los mismos valores que el script de Tolokoban. Pero si tiene un SVG como <svg width="100px" height="100" viewBox="0 0 200 200"> , solo esta versión le dará los resultados correctos.
Intenta usar getBoundingClientRect() : 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); }Las soluciones propuestas son excelentes, pero no funcionarán en todos los escenarios.
La publicación del OP se titula
¿Cómo obtener las coordenadas de clic en relación con el elemento SVG que contiene el oyente onclick ?
Entonces, si coloca el oyente onclick en su elemento svg raíz, cada vez que haga clic en cualquiera de sus elementos secundarios, getBoundingClientRect le dará el Rect del niño y no obtendrá las coordenadas de clic relativas al svg raíz.
Este fue mi caso, ya que necesitaba las coordenadas relativas a la raíz en todo momento, y la solución que funcionó para mí fue usar e.target.farthestViewportElement . Aquí hay un extracto de mi código (JSX):
const onClickSvg = e => { const { farthestViewportElement: svgRoot } = e.target; const dim = svgRoot.getBoundingClientRect(); const x = e.clientX - dim.left; const y = e.clientY - dim.top; console.log(`x: ${x}, y: ${y}`); }; <svg onClick={onClickSvg}>...</svg>