Here is a fiddle of what actually have. https://jsfiddle.net/Lofdujwr/
I'm using a library for zoom and pan an SVG svgpanzoom. I have a button when clicked it zooms on spain for example, so I put the coordinates in:
$("#spain").on("click", function() {
panZoom.zoomAtPoint(12, {x: 188, y: 185});
});
The problem is when I resize the page that coordinates doens't work anymore I need to recalculate them, I have found a function that might work but I don't know how to use it:
var s = instance.getSizes()
var p = instance.getPan()
var relativeX = s.width / 2 / (p.x + s.viewBox.width * s.realZoom)
// After resize
var s = instance.getSizes()
var p = instance.getPan()
var x = (s.width / 2 / relativeX) - s.viewBox.width * s.realZoom
instance.pan({x: x, y: 0})
And another question, is it possible to get coordinates from a path ID inside the svg for example?
EDIT: Seems like I have to calculate the actual X and Y viewport from my svg and then recalculate it giving my point (x:188, y: 185) on 0.0 viewport, anyone know any example I can see?
To answer the actual question:
The plugin you are using is controlling the transforms by changing the matrix of g.svg-pan-zoom_viewport
and not the viewBox
of the svg
.
In your function cursorPoint()
you keep transforming the mouse-coordinates referring to the svg
, yet you discard the underlying transformation on g.svg-pan-zoom_viewport
. That is the reason why you are getting different coordinates while the svg
is either resized or moved (=transformed).
If you refer the coordinates to the g.svg-pan-zoom_viewport
instead, you will get consistent results.
function cursorPoint(evt){
pt.x = evt.clientX; pt.y = evt.clientY;
//return pt.matrixTransform(svg.getScreenCTM().inverse());
var tGroup = document.querySelector('.svg-pan-zoom_viewport');
return pt.matrixTransform(tGroup.getScreenCTM().inverse());
}
Another way would be to change the viewBox
of the svg
instead of using the groups matrix. Yet since your plugin works that way, you should go with it.
Update
I played around with that linked plugin a bit and for me the function zoomAtPoint()
is doing something wrong. Let us assume Spain in the linked fiddle is at 165:165. Now to constantly zoom to that location correctly you need to reset it before:
panZoom.reset();
panZoom.zoomAtPoint(6, {x: 165, y: 165});
Else the function either does nothing or zooms somewhere else.
Now to get the coordinates of "argentinia" and zoom to it:
panZoom.reset();
//REM: Apparently the values need some time to adjust after reset() is called, yet is seems to have no callback.
window.setTimeout(function(){
var tViewport = document.querySelector('g.svg-pan-zoom_viewport');
var tMatrix = tViewport.transform.baseVal.getItem(0).matrix;
var tBBox = document.querySelector('#argentina').getBBox();
var tPoint = {x: (tBBox.x + tBBox.width / 2) * tMatrix.a + tMatrix.e, y: (tBBox.y + tBBox.height / 2) * tMatrix.d + tMatrix.f}
//REM: Approximate values, I leave the exact calculation up to you.
panZoom.zoomAtPoint(6, tPoint);
}, 500)
Working fiddle with example buttons: https://jsfiddle.net/04Lg9ruj/