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.
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?
Once #1339/#1682 is merged, it would be possible to say “fit to this bounding box with a top padding”.
I see. Cool.
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
});
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.)
@lucaswoj Thanks for suggesting 'around'. Couple of remarks:
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?
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?
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.
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.
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)
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?
+1 Would be awesome if this was added as a feature.
+1 I could use this as well
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.
Any ETA on this feature? Working with padding + offset can be really tricky in some cases. Thanks! :)
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.
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.
@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.
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.
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.
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.
@peterqliu What about performances if the map is shifted off canvas? Are "invisible" tiles still loaded?
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!
@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
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.
@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?
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 https://github.com/mapbox/mapbox-gl-js/issues/1740#issuecomment-164532027 https://github.com/mapbox/mapbox-gl-js/issues/1740#issuecomment-191133889.
@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.
@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
Thanks for triaging this @mollymerp. 😄
To make next steps more concrete, I'm have split this into two tickets:
around
parameter available (using the NavigationControl
) https://github.com/mapbox/mapbox-gl-js/issues/4268 on Mobile, Interacting with Mapbox gl map causing additional page movement.Does any else having this issue?
@swathi-kajjam overflow:hidden
on the map object should solve this
team, any updates on this one? it's been a while
@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...?
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.
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.
Most helpful comment
+1 I could use this as well