I\'m experimenting with dynamically drawing things on an SVG element based on the position of the mouse. Unfortunately, I\'m having difficulty translating the mouse coordinates
Don't use getBoundingClientRect()
. Instead, transform the point from screen space into global SVG space by using getScreenCTM()
:
var pt = demo.createSVGPoint(); // demo is an SVGElement
demo.addEventListener('mousemove',function(evt) {
pt.x = evt.clientX;
pt.y = evt.clientY;
var svgGlobal = pt.matrixTransform(demo.getScreenCTM().inverse());
// svgGlobal.x and svgGlobal.y are now in SVG coordinates
},false);
If you need to transform from screen space into the local transform for an element, use getTransformToElement()
to transform the point further:
var elTransform = demo.getTransformToElement(someElement);
var elLocal = svgGlobal.matrixTransform(elTransform );
getTransformToElement()
: http://jsfiddle.net/7kvkq/4/For better performance, instead of transforming the point twice and creating an intermediary point, combine the matrices into one and use that to transform your coordinates:
var demo = document.querySelector('svg'),
pt = demo.createSVGPoint(),
g = demo.querySelector('#myGroup');
// Assumes that the group does not move with respect to the SVG;
// if so, re-calculate this as appropriate.
var groupXForm = demo.getTransformToElement(g);
demo.addEventListener('mousemove',function(evt) {
pt.x = evt.clientX;
pt.y = evt.clientY;
var xform = groupXForm.multiply(demo.getScreenCTM().inverse());
var localPoint = pt.matrixTransform(xform);
// localPoint.x/localPoint.y are the equivalent of your mouse position
},false);
You can see a demo using these techniques on my site:
http://phrogz.net/svg/drag_under_transformation.xhtml