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

Add a global "padding" option #4268

Closed
lucaswoj opened this issue Feb 14, 2017 · 23 comments
Closed

Add a global "padding" option #4268

lucaswoj opened this issue Feb 14, 2017 · 23 comments
Labels
feature 🍏 GL native → GL JS For feature parity with Mapbox Maps SDK on a native platform

Comments

@lucaswoj
Copy link
Contributor

We allow users to pass an around option to some camera methods.

This ticket proposes a around option be added to Map as a constructor option, getter, and setter.

This option would specify a default value for around on all camera mutations so that

  • it becomes possible to specify around for implicit camera mutation, such as those triggered by use of the NavigationControl
  • it becomes more ergonomic to use the same around value for all camera mutations

Open Questions

  • Does around make sense semantically in this case? Many users will be using this feature because they have a translucent element over the map. In that use case, padding is a more intuitive option.
  • Might users be confused about the difference between around and center? Can we find a naming convention that eliminates that confusion?
  • Are there any other parameters that should have global defaults like this?
@1ec5
Copy link
Contributor

1ec5 commented Feb 14, 2017

A padding option would avoid the potential confusion between center and around. We do need to make sure padding accepts all four edges independently, both for consistency with related style specification properties and so that we address the use case that originally prompted this cluster of tickets.

Another important aspect is that it becomes all the more important to provide a method that returns the current CameraOptions, accepting a padding option. The developer should be able to call something like jumpTo(getCamera(padding), padding) and count on the viewport to stay constant.

@mourner
Copy link
Member

mourner commented Feb 15, 2017

I don't think it makes sense to have a global around option, because the value you need for it depends on context (e.g. the current map view). I have a hard imagining a use case where it would be static.

padding makes sense though because it's usually static. I would introduce independent padding for 4 sides because it's one of the most common use cases — e.g. having a semi-transparent sidebar on the map.

@1ec5 1ec5 added the GL native → GL JS For feature parity with Mapbox Maps SDK on a native platform label Feb 15, 2017
@lucaswoj lucaswoj changed the title Add a global "around" option Add a global "padding" option Feb 16, 2017
@musicformellons
Copy link

musicformellons commented Apr 26, 2017

It's been a while since I brought up this issue referring then to it as 'shifted center'. I am now trying to establish what current status is. I note that in the meantime padding is added, but am I right that then you would have to set all flyTo etc kind of operation explicitly with offset to the 'shifted center', whereas this issue would have this setup instantly for all kinds of zoom operations? So maybe just wait a little till this is implemented?

@mourner
Copy link
Member

mourner commented Apr 26, 2017

@musicformellons yes, that's right. I still think a global map padding option makes more sense than individual offset options in various camera methods, but we don't have a timeline for implementing this at the moment.

@jaapster
Copy link

jaapster commented Jan 9, 2018

I would also prefer global map padding as this would also apply to box zooming.

@stevage
Copy link
Contributor

stevage commented Jan 15, 2018

Thanks @mourner for noticing this duplicate. Copying my text in from that issue since I think it covers another use case, with much the same proposed solution:

Currently a map's maxBounds specifies that the four corners of the map will never be outside the lat/long boundaries of the maxBounds. I am finding that sometimes this isn't ideal, when you have controls or overlays sitting inside the map area.

A concrete example:

  • I have the western boundary of maxBounds set to 140, which is the western boundary of the state of Victoria. (This particular map is for a state-based agency). Minzoom is 6 (which shows the whole state).
  • There is a legend sitting just inside the left margin of the map, 315px wide out of 890px. (It's not very tall, so doesn't obscure much space).
  • Problem: when the user zooms out fully, part of the state is obscured by the legend.
  • Solution 1: move the western boundary of maxBounds a lot further west, which isn't ideal, as it creates a huge amount of area where the user could get lost, at higher zooms.
  • Solution 2: decrease minZoom, which creates more issues for data preparation and cartography, and also doesn't totally solve the problem of the user wanting to see lots of the state at a higher zoom level.

Proposed solution: allow some kind of maxBoundsBuffer setting which changes the definition of maxBounds. Instead of the four corners being constrained to the maxBounds, a rectangle inset by maxBoundsBuffer will be constrained. So in my case, the user could pan 315px further left than currently, so the legend doesn't obscure the map.

@59023g
Copy link

59023g commented Feb 20, 2018

Hey, Updates on this?

@songololo
Copy link

Since you use the thumbs-up to track the priority of these items, and since the parent issue from which this item was split had 26 thumbs up plus the 9 above I hope that makes for a total of 35 thumbs-up! ;)

@cyrilchapon
Copy link

cyrilchapon commented Jul 17, 2018

Any update on this ?

What I'm trying to build is a "virtual center" for my map, which covers every animations / fitBounds / zoom etc. The point is we have a semi-transparent control-panel overlay, and trying to distinguish the "visible zone" of the "useful zone" on the canvas.

Thus, we're trying to make every (programmatic) interractions respecting a padding corresponding to the "useful zone"

@songololo
Copy link

songololo commented Aug 6, 2018

It is now 2 years, 8 months, 17 days since the original issue was raised: #1740

Any hope or updates for those of us holding out for this feature?

#3890 (padding options for fit bounds) doesn't help for this use-case because it assumes a bearing of 0º and a pitch of 90º. i.e. it is absolute and not relative to already existing transformations of the map.

A request: Is there please some way to keep track of thumbs-ups from closed issues when splitting into new issues. The issues priority list doesn't take into account that the original issue also has 32 thumbs-up and 9 hearts, plus the 19 (albeit some duplicates no-doubt) from this issue. i.e. this issue is arguably the highest priority feature request yet this is not reflected.

@igal1c0de4n
Copy link

Team, would be great to have an update here. Is it even on the road map for the nearby future?
We depend on the platform and need to know what to expect

@bruno-vaz
Copy link

Since this feature looks unlikely to be implemented, is there any workaround on that?
I'm developing a PWA that has a map covering the entire screen, but the UI covers half of that initially, and I'm having trouble to wrap my mind around this, looks like it should be really simple but it's not.

@khollund
Copy link

khollund commented Nov 7, 2018

I have a map where I have the UI covering 1/3 to 1/2 of the screen. I started out by having padding to always offset the center position, but it was a pain as I had so much logic revolving around center point, I found the performance was much better by just resizing the map and not drawing it under the UI. But if your UI doesn't allow that my previous solution might work. What's your specific needs when it comes to interaction between UI and map?

@bruno-vaz
Copy link

I have a map where I have the UI covering 1/3 to 1/2 of the screen. I started out by having padding to always offset the center position, but it was a pain as I had so much logic revolving around center point, I found the performance was much better by just resizing the map and not drawing it under the UI. But if your UI doesn't allow that my previous solution might work. What's your specific needs when it comes to interaction between UI and map?

https://codepen.io/bruno-vaz/full/vQLBGX/

The indigo div is the map, the main interface could be scrolled to see more or less of the map, in the application I'll have code that snaps the scroll position to one of 3 options:

  • The initial one, with the white UI in the "middle" of the screen
  • White UI at the top, hiding the map
  • White UI at the bottom, revealing more of the map

So I would have 2 center settings, one for the "fullscreen" map and another for the "halfscreen" map.
I have some interactions in the map that needs to have an offset in the zoom, when the user clicks on a marker cluster, it centers it and zooms in it, and when the user clicks on a marker, it centers it.
I'm thinking that since it's only 2 interactions involving centering things, maybe it wouldn't be so hard to offset the interactions themselves.

@khollund
Copy link

khollund commented Nov 7, 2018

I work in React, and I just stored center in state, along with the ui dimensions, and then always fed it padding according to the state of the UI. No matter if user or code initiated a move. That said, I felt it got complicated, if you don't have any transparency on the UI you might as well just resize the map, or at least try that function and see how it performs.

@musicformellons
Copy link

@bruno-vaz So you don't have 'ordinary zoom in / out' (by pinching or scrollmouse or via the + - widget) then? This can easily be forgotten, but it is also weird when you zoom and the parts of the map you are interested in 'walk out of your screen' (so especially on zoom in). As a user you always assume that the center of you map 'stays' in view.

@musicformellons
Copy link

musicformellons commented Nov 7, 2018

@khollund It got complicated, but it worked fine? If so, I might try your approach.

@khollund
Copy link

khollund commented Nov 7, 2018

@khollund It got complicated, but it worked fine? If so, I might try your approach.

I would say it depends on the complexity you already have around it. Basically everything that panned to a polygon or centered to a point by code I would pipe through a set bounds function that added padding and then I would set bounds instead of setCenter. In broad terms.
For all user interaction I'd just ignore that. There's a few edge cases where it wasn't perfect, but it was very much usable. I just didn't like the added layer of complexity and found I could just resize the map with my UI instead as that also saves some rendering.

@bruno-vaz
Copy link

@bruno-vaz So you don't have 'ordinary zoom in / out' (by pinching or scrollmouse or via the + - widget) then? This can easily be forgotten, but it is also weird when you zoom and the parts of the map you are interested in 'walk out of your screen' (so especially on zoom in). As a user you always assume that the center of you map 'stays' in view.

Only pinch and scroll to zoom, but then it zooms where the user pinches/scrolls so it won't be a problem.

@steveattewell
Copy link

@bruno-vaz Since this feature looks unlikely to be implemented, is there any workaround on that?
I'm developing a PWA that has a map covering the entire screen, but the UI covers half of that initially, and I'm having trouble to wrap my mind around this, looks like it should be really simple but it's not.

I was looking for a 'proper' solution which led me here, but I have a CSS hack / workaround. See attached screenshot in case it's useful to others.

Screenshot 2019-03-25 at 10 45 10

This is a fullscreen PWA. Note the CSS on the #map div. Set 'top' to 0 and 'bottom' to -200px. This moves the centre point to 200px below the centre of the screen because you've basically drawing an unused extra 200px of map at the bottom that's never seen by the user.

It's a waste of cpu (rendering 200px of unseen map) but means no other coding necessary because all rotate, zoom, etc. functions now focus around this lower center-point. My app does this to simulate the standard "follow me" kind of view of a sat-nav where the centre point is lower down the map.

If your interface is sometimes over the bottom of the screen, I suspect you'll want to have top:-200px, bottom:0 or similar (to move the center point up the screen).

@khollund
Copy link

I used to have an offset center and had the map under the UI, but I ended up rewriting it to have the map drawn only where it is visible, and then I resize the map on window.resize etc. Seems to work better for me tbh.

@caboe
Copy link

caboe commented Jul 22, 2019

You can use the turf distance function (http://turfjs.org/docs/#destination) to calculate a virtual new center.
Given you have constructed your cameraOptions object, you can calculate the new center this way:

const point = cameraOptions.center.toArray();
const distance = 0.1;
const bearing = cameraOptions.bearing || 0;
const viewCenter = destination(point, distance, bearing);
const [lng, lat] = viewCenter.geometry.coordinates;
const center = new LngLat(lng, lat);
const viewOptions: CameraOptions = {
...cameraOptions,
center
};

This sets the new center 100 meters in front of your regular center, so the marker gets closer to the viewer.
Then you can call the for example easeTo function easily with the new object:
mapObj.easeTo(viewOptions);

PS: the only thing that has to be done is to take the zoom into the distance calculation. Did not find a proper way to do so....

@andrewharvey
Copy link
Collaborator

Addressed by #8638

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