Mouse position inside autoscaled SVG

javascript, svg

Solution

See this code, which not only shows how to transform from screen space to global SVG space, but also how to transform a point from SVG space into the transformed space of an element: http://phrogz.net/svg/drag_under_transformation.xhtml

In short:

// Find your root SVG element
var svg = document.querySelector('svg');

// Create an SVGPoint for future math
var pt = svg.createSVGPoint();

// Get point in global SVG space
function cursorPoint(evt){
  pt.x = evt.clientX; pt.y = evt.clientY;
  return pt.matrixTransform(svg.getScreenCTM().inverse());
}

svg.addEventListener('mousemove',function(evt){
  var loc = cursorPoint(evt);
  // Use loc.x and loc.y here
},false);

Edit: I've created a sample tailored to your needs (albeit only in global SVG space): http://phrogz.net/svg/rotate-to-point-at-cursor.svg

It adds the following method to the above:

function rotateElement(el,originX,originY,towardsX,towardsY){
  var angle = Math.atan2(towardsY-originY,towardsX-originX);
  var degrees = angle*180/Math.PI + 90;
  el.setAttribute(
    'transform',
    'translate('+originX+','+originY+') ' +
      'rotate('+degrees+') ' +
      'translate('+(-originX)+','+(-originY)+')'
  );
}

Problem

I am experiencing troubles concerning the position of mouse cursor inside my SVG document. I'd like to design a potentiometer that will follow the cursor when dragged, using JavaScript in an HTML page. I tried `evt.clientX/Y` and `evt.screenX/Y` but as my SVG is in autoscale, coordinates inside my SVG are different. I have been searching for an answer for days now but I couldn't find any solution (either knowing my SVG rescaling factor in real time or have a function for mouse location in SVG coordinates system). The rotation will follow a simple rule: ``` 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; ``` With `(xc;yc)` as center of rotation and replacing all `evt.screenX/Y` by the coordinates of the mouse inside my SVG.

Original source