javascript – SVG country map scaling relative to the selected county

Question:

There is an SVG map of the country. It is necessary to achieve the effect so that when clicking on the district, scaling occurs relative to the center of the selected district, i.e. transfrom-origin must be in the center of the selected county. I would like to do without any libraries .

  1. The first question is why here , when the viewBox is set, the polygon 's built from the points received from getBoundingClientRect() do not match the svg , map and e.target elements themselves?
  2. If you add coefficients, like here , then what should be the values ​​of viewBoxMapCoefX1 and viewBoxMapCoefX1 so that the resulting mapPolygon matches the map ?
  3. If you scale the map with:

     // ANIMATION HERE map.style.transformOrigin = transformOriginX + "px " + transformOriginY + "px"; map.style.transform = "scale(" + scale + ")";

    it looks like the value of transformOrigin is wrong. If you try to change the viewBox :

     // ANIMATION HERE svg.viewBox.baseVal.x = bounding.left; svg.viewBox.baseVal.y = bounding.top; svg.viewBox.baseVal.width = bounding.width; svg.viewBox.baseVal.height = bounding.height;

    how then can you make a smooth scale animation only with CSS ( without SMIL )?

I would be grateful for any help and advice on the matter.

Answer:

1) You need to use .getBBox() instead getBoundingClientRect() to get the coordinates relative to the SVG itself, not the screen. Result .

3) Instead of scaling the map relative to the center of the selected subject ( transformOrigin + scale ), you can get the center of the subject in % instead of px and move it to the center of the map, and then do the scaling, i.e.:

// ANIMATION HERE
var transformOriginXPercent = (50 - transformOriginX * 100 / mapBounding.width) * scale;
var transformOriginYPercent = (50 - transformOriginY * 100 / mapBounding.height) * scale;
var scaleText = "scale(" + scale + ")";
var translateText = "translate(" + transformOriginXPercent + "%," + transformOriginYPercent + "%)";

map.style.transformOrigin = "50% 50%";
map.style.transform = translateText + " " + scaleText;

and thereby achieve the desired result .

In general, the issue is resolved, but I wonder how you can achieve the same effect using:

map.style.transformOrigin = (transformOriginX) + "px " + (transformOriginY) + "px";
map.style.transform = "scale(" + scale + ")";

choosing the right coefficients for transformOriginX and transformOriginY

Scroll to Top