SFML community forums

Help => Window => Topic started by: roccio on May 29, 2014, 05:09:37 pm

Title: Map View Zoom
Post by: roccio on May 29, 2014, 05:09:37 pm
Hello,
I would like to implement a zoom function like the one found in google maps (so that I zoom keeping the point where the mouse is as a "zoom focus") using a single big image as background and the as::view class.

Any help on how to implement such a feature?

thank you
Title: Re: Map View Zoom
Post by: Ixrec on May 29, 2014, 09:15:26 pm
sf::View, sf::Event::MouseWheelEvent and sf::Mouse::getPosition() should be all you need.  Just read the tutorials and documentation on them.
Title: Re: Map View Zoom
Post by: roccio on May 30, 2014, 09:38:42 am
Yes, I have something functioning right now, but my problem is that I don't want to zoom the center of the window, but where is pointed the mouse cursor (as in google maps).
The final result will be that the point under mouse cursor will always be visible as you zoom in or out.
Title: Re: Map View Zoom
Post by: G. on May 30, 2014, 01:41:00 pm
When you zoom, set the center of your view to somewhere between its current center and the mouse pointer. (or to the mouse pointer directly)
Title: Re: Map View Zoom
Post by: roccio on May 30, 2014, 02:42:51 pm
Sorry, but I can't figure out the solution.
So I try posting the code just  for clarity... (use an image as you like)

#include <SFML/Graphics.hpp>

sf::Sprite  g_sprite;
sf::Texture g_texture;

sf::FloatRect getViewBounds(const sf::View &view)
{
    sf::FloatRect rt;
    rt.left = view.getCenter().x - view.getSize().x/2.f;
    rt.top  = view.getCenter().y - view.getSize().y/2.f;
    rt.width  = view.getSize().x;
    rt.height = view.getSize().y;
    return rt;
}

float posx,posy;
float g_zoom[] = {2.0f, 1.5f, 1.0f, 0.8f, 0.6f, 0.4f, 0.2f, 0.1f};
int currentZoom = 2;

int main()
{
    // create the window
    sf::RenderWindow window(sf::VideoMode(1024, 768), "Moving Map");
    window.setVerticalSyncEnabled(true);
    sf::View view;
    view.setSize(1024, 768);

    // load map
    g_texture.loadFromFile("map.png");
    g_sprite.setTexture(g_texture);
    g_sprite.setPosition(0, 0);

    posx = 0;
    posy = 0;

    // run the program as long as the window is open
    while (window.isOpen())
    {
        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
            else
            if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
                window.close();
            else
            if (event.type == sf::Event::MouseWheelMoved)
            {
                currentZoom += event.mouseWheel.delta;
                if (currentZoom < 0) {currentZoom = 0;}
                else if (currentZoom > 7) {currentZoom = 7;}

                sf::Vector2i localPos = sf::Mouse::getPosition(window);
                sf::Vector2f realPos = window.mapPixelToCoords(localPos);

                view.setSize(1024*g_zoom[currentZoom],768*g_zoom[currentZoom]);
            }
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
           posx -= 10;

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
           posx += 10;

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
           posy -= 10;

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
           posy += 10;

        view.setCenter(posx, posy);

        // clear the window with black color
        window.clear(sf::Color::Black);

        // set view
        window.setView(view);

        // draw everything here...
        window.draw(g_sprite);

        // end the current frame
        window.display();
    }

    return 0;
}
 
Title: Re: Map View Zoom
Post by: Syntactic Fructose on May 30, 2014, 04:08:31 pm
Post minimal code to your problem, if you want people to help you could at least spend the time to break down what chunks of code are relevant to the question and make it easier for everyone.
Title: Re: Map View Zoom
Post by: roccio on May 30, 2014, 05:01:26 pm
Post minimal code to your problem, if you want people to help you could at least spend the time to break down what chunks of code are relevant to the question and make it easier for everyone.

It's just a minimal code, the problem is in the sf::Event::MouseWheelMoved event, where the zoom is performed.

this is the zoom code
view.setSize(1024*g_zoom[currentZoom],768*g_zoom[currentZoom]);

I have tried before with the view.zoom, but it is not "absolute", and I need fized zoom factors.
Title: Re: Map View Zoom
Post by: Ixrec on May 30, 2014, 07:48:50 pm
Your code looks like it's on the right track, so since you forgot to tell us what's wrong with it, I have no idea how to help you fix it.
Title: Re: Map View Zoom
Post by: roccio on May 31, 2014, 02:18:26 pm
Ok, my problem is that I want to zoom centered where the mouse is, not the center of the screen as in my test application. So if I put the mouse on a spot in the map and move the mouse wheel, I would like to zoom in/out keeping that spot always visible. Just as in google maps.

Title: Re: Map View Zoom
Post by: Ixrec on May 31, 2014, 02:24:28 pm
My guess would be you forgot to do something with the "realPos" variable.  You seem to be computing it correctly (ie, using mapPixelToCoords) but I don't see it getting used anywhere.