Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scale SVG around center with plain javascript

I have a problem maybe understanding well how coordinates work ins SVG. I have a javascript function that scales an svg graphic such as that:

var g = document.getElementById("graph");
var nm = g.getCTM().multiply(k); //k is the scale factor
g.setAttribute("transform", "matrix(" + nm.a + "," + nm.b + "," + nm.c + "," + nm.d + "," + nm.e + "," + nm.f + ")");

The point is that after scaling the center is slightly translated so the graphic loses is "geographic" center. How can I determine which translation I need to have to scale the graphic "around" its center?

Thanks.

like image 735
kandan Avatar asked Dec 13 '12 12:12

kandan


2 Answers

Have you considered other approaches?

If you just looking for zoom in/out on an svg, it might be easier to do it differently, e.g.: http://www.cyberz.org/blog/2009/12/08/svgpan-a-javascript-svg-panzoomdrag-library/

I had the same problem a while ago and ended up creating my own zoom using this: https://github.com/rstacruz/jquery.transit

You basically use css transform scale for a svg wrapper and svg adjusts nicely. You can even animate the zooming.

like image 163
Dziad Borowy Avatar answered Dec 10 '22 21:12

Dziad Borowy


As I think fits better my purpose and after reading how to do it in the helpful link

http://commons.oreilly.com/wiki/index.php/SVG_Essentials/Transforming_the_Coordinate_System#The_scale_Transformation

I have changed it to scale the graphic around the position of the mouse when its wheel is scrolled,

If it helps this is the code (using SVGPan's setCTM method):

var svgRoot = document.getElementsByTagName("svg")[0];
var g = svgRoot.getElementById("viewport");

var newp = svgRoot.createSVGPoint();
newp.x = evt.clientX;
newp.y = evt.clientY;
newp = newp.matrixTransform(g.getScreenCTM().inverse());

var oldx = newp.x;
var oldy = newp.y;

//z = scale factor
setCTM(g, g.getCTM().translate(-(oldx*(z-1)),-(oldy*(z-1))).scale(z));
like image 21
kandan Avatar answered Dec 10 '22 20:12

kandan