-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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 user to specify n, s, e, w padding options for fitBounds #3890
Conversation
ready for your 👀 @lucaswoj |
js/ui/camera.js
Outdated
@@ -303,32 +303,58 @@ class Camera extends Evented { | |||
* {@link Map#easeTo}. If `false`, the map transitions using {@link Map#flyTo}. See | |||
* {@link Map#flyTo} for information about the options specific to that animated transition. | |||
* @param {Function} [options.easing] An easing function for the animated transition. | |||
* @param {number} [options.padding=0] The amount of padding, in pixels, to allow around the specified bounds. | |||
* @param {number|Object} [options.padding] Sets padding around the given bounds on each side in pixels. Accepts a number for all padding edges or an object with padding for each compass direction (north, south, east, and west) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can provide a more specific type definition by creating a PaddingOptions
@typdef
for {north: Number; east: Number; south: Number; west: Number;}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok! will investigate
js/ui/camera.js
Outdated
@@ -303,32 +303,58 @@ class Camera extends Evented { | |||
* {@link Map#easeTo}. If `false`, the map transitions using {@link Map#flyTo}. See | |||
* {@link Map#flyTo} for information about the options specific to that animated transition. | |||
* @param {Function} [options.easing] An easing function for the animated transition. | |||
* @param {number} [options.padding=0] The amount of padding, in pixels, to allow around the specified bounds. | |||
* @param {number|Object} [options.padding] Sets padding around the given bounds on each side in pixels. Accepts a number for all padding edges or an object with padding for each compass direction (north, south, east, and west) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are your thoughts about providing geographic padding options (north
, east
, ...) vs screen padding options (top
, left
, ...)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think screen padding options make more sense but would be more complicated to implement... 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just did a little experimentation with this PR and discovered that Map#fitBounds
always resets the bearing to 0 when it is called. 🤔
We may be able to rename these properties, ship this PR as-is, and open a separate issue about preserving bearing during a Map#fitBounds
operation.
js/ui/camera.js
Outdated
* @see [Fit a map to a bounding box](https://www.mapbox.com/mapbox-gl-js/example/fitbounds/) | ||
*/ | ||
fitBounds(bounds, options, eventData) { | ||
|
||
options = util.extend({ | ||
padding: 0, | ||
padding: { | ||
north: 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes more sense to name these top
, right
, bottom
and left
. It's more consistent with Leaflet and Google Maps APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. If fitBounds is called on a (potentially) rotated map n, s, e and w don't make sense as you would want the padding to be applied to the viewport, not the feature.
fa5ad12
to
53dad67
Compare
I updated the approach to one @lucaswoj and I discussed a couple weeks ago where we separate the padding out into two parts: the part that does not alter the center of the map (i.e. equal padding amts on top/bottom and left/right) and the part that does (any left over padding from the first part) and the latter part gets added to the offset object which is handled in subsequent calls to So if you pass a padding object like This was a compromise to get accurate results without completely refactoring the camera 😅 -- the same results are achievable with the current API, but hopefully this option will be more clear to users going forward. |
8920c87
to
6e2db2b
Compare
@lucaswoj I also added a typedef for the |
@mollymerp 👍 on the typedef. The typedef is the most semantically correct. I hope we'll have an oppurtunity to refactor when we hit #2801. I also hope we'll add better support for |
6e2db2b
to
57be827
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure about the need to support both offset
and padding
. The relationship between the two is a little confusing. padding
alone should be functionally sufficient.
Could we deprecate offset
and remove it in a future release?
src/ui/camera.js
Outdated
console.log(Object.keys(options.padding).sort((a, b)=> { | ||
if (a < b) return -1; | ||
if (a > b) return 1; | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
accidental console.log
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As best I can tell, these lines are equivalent to .sort((a, b)=> a - b)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I don't think they're equivalent... according to the docs the approach you suggest can be used for comparing numeric values, but not for strings.
Given that this is one of the most requested features, maybe we should merge and this in advance of a larger refactor of the Camera API + documentation? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me, barring a couple of minor suggestions.
Regarding the redundancy between offset and padding: while I agree that the redundancy could be confusing, this is a case where parsimony might be more confusing, because while they're functionally redundant, they represent distinct use cases, and it's hard (or at least annoying) to convert between them.
src/ui/camera.js
Outdated
* | ||
* @memberof Map# | ||
* @param {LngLatBoundsLike} bounds Center these bounds in the viewport and use the highest | ||
* zoom level up to and including `Map#getMaxZoom()` that fits them in the viewport. | ||
* @param {Object} [options] | ||
* @param {AnimationOptions | CameraOptions | PaddingOptions} [options] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way I read this, it makes me think that top
, bottom
, etc. are properties that can go directly on options
. Since these should actually be sub-properties of options.padding
, should this be @param {number|PaddingOptions} [options.padding=0] The amount of padding to allow around the given bounds.
(or something less stilted-sounding heh)
test/unit/ui/camera.test.js
Outdated
const bb = [[-133, 16], [-68, 50]]; | ||
|
||
camera.fitBounds(bb, {duration:0}); | ||
t.deepEqual(fixedLngLat(camera.getCenter()), { lng: -100.5, lat: 34.717077774 }, 'pans to coordinates based on fitBounds'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small preemptive suggestion: should we round the latitude before comparing it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixedLngLat
does round to a default precision of 9 decimal places – that is rather precise, though, so it might be a good idea to reduce precision a bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh whoops 🙈 totally didn't see that!
Per chat with @mollymerp today, we're going to 🚢 this API and look to make simplifying + breaking changes in conjunction with #2801 |
Launch Checklist
Continuing on @tristen's PR from #1682.
In order to have separate padding pixels on each side of the map bounds. Right now its set up as
[n,e,s,w]
but I'm not sure this makes the most sense. Should we be consistent with theoffset
option and take 2Points
(one for each corner of the bounds)?Testing the debug page is showing me I'm slightly off on the adjustments right now so I have to figure out what I did wrong in adjusting the camera function.flipped x, y 😭cc @lucaswoj
closes #1339