Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Map View Zoom  (Read 5189 times)

0 Members and 1 Guest are viewing this topic.

roccio

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
    • Email
Map View Zoom
« 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

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Map View Zoom
« Reply #1 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.

roccio

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
    • Email
Re: Map View Zoom
« Reply #2 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.

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: Map View Zoom
« Reply #3 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)

roccio

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
    • Email
Re: Map View Zoom
« Reply #4 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;
}
 

Syntactic Fructose

  • Jr. Member
  • **
  • Posts: 80
  • Overflowing stacks and eating snacks
    • View Profile
Re: Map View Zoom
« Reply #5 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.

roccio

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
    • Email
Re: Map View Zoom
« Reply #6 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.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Map View Zoom
« Reply #7 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.

roccio

  • Jr. Member
  • **
  • Posts: 64
    • View Profile
    • Email
Re: Map View Zoom
« Reply #8 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.


Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Map View Zoom
« Reply #9 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.

 

anything