SFML community forums
Help => Graphics => Topic started by: MickeyKnox on May 31, 2012, 07:32:21 pm
-
I would like to be able to zoom like in googlemaps, meaning that the mouse
cursor does not only stay at the same screen coordinates while zooming, but
also on the same map coordinates.
The relevant code in the event handling section looks somewhat like this:
178 case sf::Event::MouseWheelMoved:
179 {
186 float zoom = event.mouseWheel.delta > 0 ? 0.5f : 2.f;
187 sf::Vector2f newpos (window->getSize().x, window->getSize().y);
188 newpos /= 2.f;
189 newpos -= sf::Vector2f (sf::Mouse::getPosition(*window).x, sf::Mouse::getPosition(*window).y);
190 newpos /= zoom;
191 view.move (-newpos);
192 view.zoom (zoom);
194 break;
195 }
I played around with some of the parameters, but i can't get it to zoom towards
the mouse position. Any suggestions?
-
I'm not sure what's wrong in the math, because I didn't try to understand it.
But wouldn't it be easier if you zoomed first and then reset the view?
-
I'm not sure why you divide the pos by the zoom factor
newpos /= zoom;
If I had to implement such a thing, I think I would start moving the view to the cursor coordinates before actually zooming. Anyway, apart from what I said above, I understand what you're doing and can't say anything else without more precision (or some sleep :p)
-
Ok, well, i forgot to present the idea of what i'm doing, here it comes:
First, i calculate the vector between the mouse position and the center
of the screen. Then i scale that vector by the zoom to be applied. Lastly,
i move the view with that vector.
newpos *= zoom makes more sense, i guess, but it didn't work either.
Does it make a difference, if i zoom first and move then? Theoretically,
i mean? However, i tried it and i played around a little with subtle changes
in the ordering of things or the multiplication versus differentiation
without finding the desired result.
I think, the idea presentet above is right, but it seems like i'm missing
something or have to work around some quirks or so...
-
Well, i figured it out, the following code does the trick:
178 case sf::Event::MouseWheelMoved:
179 {
180 view.zoom (event.mouseWheel.delta > 0 ? 0.5f : 2.f);
181 zoom_factor = view.getSize ().y / window->getSize ().y;
182
183 sf::Vector2f newpos (window->getSize().x, window->getSize().y);
184 newpos /= 2.f;
185 newpos -= sf::Vector2f (sf::Mouse::getPosition(*window).x, sf::Mouse::getPosition(*window).y);
186 newpos *= event.mouseWheel.delta > 0 ? zoom_factor : zoom_factor / 2.f;
187 view.move (event.mouseWheel.delta > 0 ? -newpos : newpos);
188 break;
189 }
The trick is, the zoom i'm just about to apply is not enough, i have to scale
the vector by the overall zoom of the view.