Jump to content
  • Advertisement
Sign in to follow this  
Icebone1000

How to pin zoom at location

This topic is 1222 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a map that I can scroll (drag with mouse) and zoom.

Im trying to implement this function: 

static void PinScrollZoomAtMapPos(Vector2 mapPos_p, ScrollRect scroll_p)
    {
        // this is to make a point on the map always in the same place on the
        // screen, regardless of current zoom

        Vector2 scrolledMapPos = new Vector2(
               mapPos_p.x + scroll_p.content.localPosition.x,
               mapPos_p.y + scroll_p.content.localPosition.y
               );

        Vector2 scrolledZoomedMapPos = new Vector2(
               mapPos_p.x * scroll_p.content.localScale.x + scroll_p.content.localPosition.x,
               mapPos_p.y * scroll_p.content.localScale.y + scroll_p.content.localPosition.y
               );

        Vector2 diff = scrolledMapPos - scrolledZoomedMapPos;

        Debug.Log("diff: " + diff);

        Vector2 offseted = new Vector2(
            scroll_p.content.localPosition.x + diff.x,
            scroll_p.content.localPosition.y + diff.y
            );

        scroll_p.content.localPosition = offseted;
    }

(The scroll_p.content is the map.)

 

Although I think my logic makes sense at first, I see how it will never work, the 'diff' var should return 0 after subsequent calls to this function, but since I move the map pos, it will never happen. I dont know what I have to do..

 

Now doing this:

static void PinScrollZoomAtMapPos(Vector2 mapPos_p, ScrollRect scroll_p)
    {
        // this is to make a point on the map always in the same place on the
        // screen, regardless of current zoom

        //Vector2 scrolledMapPos = new Vector2(
        //       mapPos_p.x + scroll_p.content.localPosition.x,
        //       mapPos_p.y + scroll_p.content.localPosition.y
        //       );

        Vector2 scrolledZoomedMapPos = new Vector2(
               mapPos_p.x * scroll_p.content.localScale.x + scroll_p.content.localPosition.x,
               mapPos_p.y * scroll_p.content.localScale.y + scroll_p.content.localPosition.y
               );

        Vector2 diff = mapPos_p - scrolledZoomedMapPos;

        Debug.Log("diff: " + diff);

        Vector2 offseted = new Vector2(
            scroll_p.content.localPosition.x + diff.x,
            scroll_p.content.localPosition.y + diff.y
            );

        scroll_p.content.localPosition = offseted;
    }

Works, but the map becomes un-scrollable. I want to account only for zoom, like ignore the displace caused by the zoom (since it enlarges the map from the center).

 

Note this is different from centralizing the map at pos. The pin can be at any place, for example at 80% bottom right of the screen, say theres a city there, I want the city to keep at the exact same place on the screen, while I zoom in/out.

 

I feel is such a simple thing to do,yet Im struggling with this since yesterday.

 

 

 

 

 

 

 

Share this post


Link to post
Share on other sites
Advertisement

Indeed, it should be quite trivial.

Have you tried fractions?

 

Zoom only changes how much of the map is displayed at the screen. Imagine one dimension (eg horizontal), from the left of the displayed area to the point has length X1, and from the point to the right edge of the displayed has length Y1. When you change zoom, the distances change to X2 and Y2 respectively, where X1 + Y1 != X2 + Y2 (otherwise you have the same area displayed, ie zoom didn't change).

 

I think the trick here is to keep the fractions X1 / (X1 + Y1) and X2 / (X2 + Y2) the same. The total length of X1 + Y1 is different from X2 + Y2, but both sides of the point change 'at the same relative rate', so the point in the middle stays at the same position, relative to the start (or in 2D, relative to the top-left edge of the display).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!