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 .
- The first question is why here , when the
viewBox
is set, thepolygon
's built from the points received fromgetBoundingClientRect()
do not match thesvg
,map
ande.target
elements themselves? - If you add coefficients, like here , then what should be the values of
viewBoxMapCoefX1
andviewBoxMapCoefX1
so that the resultingmapPolygon
matches themap
? -
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