Help with viewport transformations

(Andrei) #1

I am currently stumbling a bit with the following problem:

I have a map (SVG graphic) which I present in a fixed size document. The users are allowed to zoom this map via either pinch zoom or via a zoom slider and (when zoomed) are also able to pan the map in order to explore various details. This part is working fine (is related to this topic.).

My problem is to ensure that when zooming via the zoom slide control or via the pinch zoom gesture, the scaling of the map should happen from the current center of the viewport, and not from the transform anchor point of the map element. This is obviously only relevant when the map is zoomed and panned.

Somehow I can’t quite wrap my head around the coordinate transforms that I assume are needed for this to work. Does anybody happen to have something like this implemented, and would consider sharing the project/code or any tips?

I tried porting something like this solution, which appears to work in general, but it’s really specific to a image, instead of working with a scalable div/element. I at least wasn’t able to rewrite the math part to work within Tumult. :fearful:

(Jonathan Deutsch) #2

It might be useful to see your document to see how you’re doing it.

I believe the math would just be:
image offset = (zoom point in viewport) - ((zoom point in viewport) * zoom factor)

(Andrei) #3

Thanks for taking a look at this.

Here’s the relevant part of my project regarding the map: (674.9 KB)

I put some placeholder elements in the map container, in reality there is a SVG image there, as well as several buttons / hot points etc. Shouldn’t make a difference.

What I am looking for is to make sure that when the map is zoomed in and panned from the center, whenever the user zooms (either with the slider or via pinch zoom), the actual zoom takes place from the current center of the view, and not from the anchor point of the map container. Actually, ideally - in the case of pinch zoom - from the midpoint between the fingers.

(Jonathan Deutsch) #4

I couldn’t figure out how to actually do a pinch with that example (it seems to do nothing on my iPad).

Glancing at the code, I can see that you are using the scaleX/scaleY properties - these map to a CSS transform, which use the transform origin. You may want to set that to the top/left (0% 0%) position of your elements, otherwise the scale will be from the center as 50% 50% is the default. Otherwise depending on the types of objects, you may want to use the width/height properties.