Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow map center to be configurable for all interactions and controls via an offset option #1740

Closed
musicformellons opened this issue Nov 20, 2015 · 35 comments
Assignees
Labels
feature 🍏 GL native → GL JS For feature parity with Mapbox Maps SDK on a native platform

Comments

@musicformellons
Copy link

I would like to 'flyTo center' but with a 'center' that is not the middle of my viewbox, so I need a shifted center. To make it somewhat more clear see the picture.
screenshot from 2015-11-20 10-43-46

It is a mobile device. On top of the map a picture is shown with height Q. Therefore clicked items should not fly to x, but to y (the shifted center). I tried hacking around it using a formula for center:

center: [lng, lat + (0.5 * 0.33 * (map.getBounds().getNorth() - map.getBounds().getSouth()))], 

This is the needed extra shift: 0.5 * Q height% * (north - south).

But this only works when the North of the map is at the top of the viewport, so when there is no bearing. I need it to work with a bearing as well of course.

Any suggestions how to proceed/ smarter approach?

@1ec5
Copy link
Contributor

1ec5 commented Nov 20, 2015

Once #1339/#1682 is merged, it would be possible to say “fit to this bounding box with a top padding”.

@musicformellons
Copy link
Author

I see. Cool.

@musicformellons
Copy link
Author

I am still in shock, but I actually solved/ hacked around this using 'offset'. In the Api docs offset is mentioned in general under AnimationOptions. Might be an idea to specify it under flyTo (and other applicable animations).

                var rect = document.getElementById('map').getBoundingClientRect();
                var viewportX = [rect.bottom];
                var shiftScreen = 0.5 * 0.3 * viewportX;   /// the 0.3 is the 30% padding at the screentop
                var bear = toRadius(map.getBearing());  
                var cosBear = Math.cos(bear);
                var sinBear = Math.sin(bear);

And then:

                    map.flyTo({
                        center: [lng, lat], 
                        offset: [-shiftScreen * sinBear, shiftScreen * cosBear],
                        speed: 0.8, 
                        curve: .6 
                    });

@lucaswoj
Copy link
Contributor

You might also want to look at the around parameter. That does almost exactly what you're looking for (But it does not currently work in conjunction with center. If you think it should, we should chat.)

@musicformellons
Copy link
Author

@lucaswoj Thanks for suggesting 'around'. Couple of remarks:

  • So far I did not zoom and thus 'around' was not needed/ applicable. Actually when I add a zoom my solution still works and centers and zooms nicely to the 'shifted center'. Cool.
  • I tried using around with zoom like this:
                    map.flyTo({
                        around: [lng, lat], 
                        zoom: map.getZoom() + 1,
                        speed: 0.25, // speed of flying
                        curve: 1.1  // curve of zoom
                    });

But then the around lnglat still walks out of my screen during the zoom so it is not using it as the zoomcenter...!? Seems around does not do anything..., so what do I do wrong?

  • What I would like now that you mention 'around' is to have something related. After using my hackaround I have a nice shifted center, but when I use subsequently the zoom-navigation widget to zoom in, my nice shifted center walks out of my viewport as the real center is used by the navigation. How can I link my 'shifted center' to the navigation widget? Any suggestions are welcome.

@lucaswoj
Copy link
Contributor

Do I understand correctly that you would like to set a different point as the map center for all interactions? If so, that's an interesting use case we haven't considered. I can't think of a way to do that without monkey-patching mapbox-gl-js. Would you mind sharing a little more information about your use case?

@1ec5
Copy link
Contributor

1ec5 commented Dec 14, 2015

There’s a need for similar functionality in the Mapbox iOS SDK: mapbox/mapbox-gl-native#2600. The use cases are primarily around navigation: when the map is tilted, it’s customary for the user location annotation to be weighted towards the bottom. But more generally, consider the case where there’s a translucent toolbar-like overlay at the top or bottom of the map: the map’s visual center is offset either up or down, and all interactions should take that into account.

@musicformellons
Copy link
Author

Yes. My case is indeed a translucent toolbar overlay which covers 1/3 (or more) of the map, still the map underneath contributes to orientation and aesthetics. The navigation UX is totally done in (and centered on) the 2/3 remaining screen-estate.

@acaid
Copy link

acaid commented Mar 2, 2016

I'm looking into solutions for a similar problem. I'm trying to offset the center point for all map interactions / animations to account for an overlaid element. It'd be great to have an option to offset the center by a percentage or number of pixels. I know this can be done by giving the map container a width >100% but this seems like a kludgy solution to a fairly common use case. (see: https://www.mapbox.com/tutorial-sherlock/step5-responsive.html as another example)
mapoffset

@igal1c0de4n
Copy link

igal1c0de4n commented May 1, 2016

Any updates on this issue? Has anyone figured out how to achieve the shifted center?
In leaflet I used https://github.com/Mappy/Leaflet-active-area
Maybe there's a similar plugin/API for mapboxGL?

@charris-RA
Copy link

+1 Would be awesome if this was added as a feature.

@adcooley
Copy link

+1 I could use this as well

@lucaswoj lucaswoj changed the title How to make a 'shifted' center? Add "edgePadding" option Jul 18, 2016
@dpieri
Copy link

dpieri commented Jul 24, 2016

We also used leaflet-active-area and are in need of the same feature for mapbox-gl. A good use case for this is Mapbox Studio: You could expand and collapse the layer panel more smoothly if you could leave the map viewport alone and just move the effective map center so interactions like flyTo() still make sense.

@lucaswoj lucaswoj changed the title Add "edgePadding" option Add "edgee padding" option Jul 29, 2016
@lucaswoj lucaswoj added feature 🍏 GL native → GL JS For feature parity with Mapbox Maps SDK on a native platform labels Jul 29, 2016
@lucaswoj lucaswoj changed the title Add "edgee padding" option Add "edge padding" option Jul 29, 2016
@nicooprat
Copy link

Any ETA on this feature? Working with padding + offset can be really tricky in some cases. Thanks! :)

@pp0rtal
Copy link

pp0rtal commented Dec 5, 2016

I hope enhancements for this topic too, for now I'm increasing the mapboxGL div size a little bit to change the center to my center.
Of course it is heavy and brings new problems depending the features you use, that's just a dirty idea if you really need this.

@lucaswoj
Copy link
Contributor

lucaswoj commented Dec 5, 2016

This feature hasn't yet come up as a priority for the GL JS team at Mapbox. The fastest way to get this feature to appear in GL JS is to submit a PR! If that's not possible, I encourage you to add a "👍" reaction to the first post in this thread. We're using those to track which features are most desired by our users.

@peterqliu
Copy link
Contributor

@musicformellons short-term solution is extending the map's parent container beyond the viewport by twice the distance of your center shift, in the direction of your center shift. So, if you want to shift the center rightward by 100px, try right:-200px in your container's styling.

@1ec5
Copy link
Contributor

1ec5 commented Dec 6, 2016

In case it's of any help: we implemented this feature in the native SDKs in mapbox/mapbox-gl-native#3583. The key when implementing this feature is to treat the padding as a camera option (as a point of reference for the center) and to always be consistent about applying or reversing the padding when converting between the camera options exposed to the developer and the camera options used internally to compute the transform.

@musicformellons
Copy link
Author

musicformellons commented Dec 6, 2016

As this is gaining 'traction' I would like to add that my 'hack' does not work properly when there is a bearing. It seems close though as the behaviour I have when 'centering' a popup is that either goes to correct shifted center instantly or it first goes to a different spot and then when selected a second time it goes to the correct shifted center. Odd... do not have time to look into it further currently..., so a solid solution would be highly appreciated!

I do like @peterqliu 's suggestion and might look into that as I think it circumvents the bearing issue.

@musicformellons
Copy link
Author

Update: My 'hack' actually does work. The problem I described above was related to not using an updated map.getBearing() value before 'flying'. After correcting that it works like a charm.

@nicooprat
Copy link

@peterqliu What about performances if the map is shifted off canvas? Are "invisible" tiles still loaded?

@cammanderson
Copy link
Contributor

Also really keen to see this feature bump up priority (obviously there are lots of priorities!).

We are keen based on two use cases we've had;

  1. Adding an overlay on top of the map; allowing us to position center and allow a panel to sit over the top with some edges of the map still exposed. I could see some use of fitBounds/transform etc to maybe handle this, but would be convenient to be able to call camera motion calls with this edge padding internally calculated.

  2. Adding a mobile 'follow along' indicator to the map; where you can position the user at the bottom of the screen, and have a majority of the screen dedicated to the direction the user is oriented. It would be good to be able to animate the bearing, supplying the current lnglat as the position of the user, and the 'edge padding' to become the center location for where to rotate from.

I understand the "around" property can assist with zoom, which is great. The edgePadding concept I think would also be great just to have control through-out of how to handle transforms.

Will always take the opportunity to say you guys are doing a great job!

@mollymerp
Copy link
Contributor

@cammanderson @musicformellons you can use the offset option on any method that takes AnimationOptions to accommodate this use case: http://jsbin.com/mihiqihaxi/edit?html,output

Tracking issues with the documentation of the offset option here #4240

@1ec5
Copy link
Contributor

1ec5 commented Feb 9, 2017

Note that the existing offset option addresses programmatic camera changes, not camera changes due to user gestures. There's also #1339, which sounds similar but (last I checked) is still unimplemented.

@mollymerp
Copy link
Contributor

@1ec5 thanks for clarification - I don't think I understand why you'd want user gestures to be offset to from the canvas though. Wouldn't that be confusing if you try to pan to a location but you're always forced offset in one way or another?

#1339 is implemented in #3890 but there is ongoing discussion about whether it will be merged in to master.

@1ec5
Copy link
Contributor

1ec5 commented Feb 9, 2017

I don't think I understand why you'd want user gestures to be offset to from the canvas though. Wouldn't that be confusing if you try to pan to a location but you're always forced offset in one way or another?

Not if there’s a translucent overlay atop part of the map, in which case there’s a discrepancy between the center of the map element and what the user perceives the center to be. See #1740 (comment) #1740 (comment).

@musicformellons
Copy link
Author

musicformellons commented Feb 9, 2017

@mollymerp I agree with 1ec5. So everything (zooming in/out, bearing, tilting, etc.) should behave "normal" but on a different center than "normal". So I suppose all these features should have a 'customizable center' instead of the current default which is the center of the total viewport canvas. And/ or maybe an overall 'customizable center' setting for the map.

The zooming with the mouse uses the cursor as zoomcenter, which makes sense. But e.g. when zooming with the navigation widget my shifted center 'walks out of my screen' when I zoom... Regarding bearing e.g.: when on mobile I go from portrait to landscape, my (shifted) center is not my (shifted) center anymore... etc.

@mollymerp
Copy link
Contributor

@1ec5 @musicformellons got it. I'm going to change the title of this ticket to reflect the updated feature request because I think the original purpose of this ticket is covered by #3890

@mollymerp mollymerp changed the title Add "edge padding" option Allow map center to be configurable for all interactions and controls via an offset option Feb 10, 2017
@lucaswoj
Copy link
Contributor

Thanks for triaging this @mollymerp. 😄

To make next steps more concrete, I'm have split this into two tickets:

@swathi-kajjam
Copy link

swathi-kajjam commented Aug 3, 2017

on Mobile, Interacting with Mapbox gl map causing additional page movement.Does any else having this issue?

@peterqliu
Copy link
Contributor

peterqliu commented Oct 8, 2017

@swathi-kajjam overflow:hidden on the map object should solve this

@igal1c0de4n
Copy link

team, any updates on this one? it's been a while

@songololo
Copy link

songololo commented Jun 10, 2018

@igalicodean it was split into two tickets per @lucaswoj post above but no movement that I can see. Mapbox apparently uses the thumbs-up on the issues to prioritise development but since this issue was split it might be that since the child-issues restart from zero thumbs-up they aren't receiving much priority...?

@david-deepblocks
Copy link

Any updates on this? the other ticket that was split from this (#4269) is not exactly what we wanted right? I mean, I need to able to change the "center" of the map without resizing it.

@songololo
Copy link

To anyone that has ever thumbed-up or hearted this issue, or arrives here after searching about this issue:

Mapbox uses an issue tracker to sort the priority of items they work on. The more thumbs-up or hearts given to an issue, the more likely they are to mobilise the resources to work on it.

This issue, which originally had 31 thumbs up and 8 hearts, was split into new issue #4268, which only has 20 thumbs-up. Other newer issues have therefore jumped priority in the queue and, as a result, this issue appears to have languished unresolved for near on 3 years now.

So, if you could please head over to #4268 and put your thumbs-up or hearts there, it might help get this issue back on the radar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature 🍏 GL native → GL JS For feature parity with Mapbox Maps SDK on a native platform
Projects
None yet
Development

No branches or pull requests