cameraForBounds is not accounting for an asymmetrical padding in the camera center result (regression in v3.3.0 to v3.4.0)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
### mapbox-gl-js version
v3.4.0 through to v3.20.0 present this issue, however it was working in v3.3.0, so possibly a regression caused by #13126
### Browser and version
_No response_
### Expected behavior
`cameraForBounds` will return a `center` and `zoom` required to fit the map to a given bounds, accounting for an optional padding. However when using an asymmetrical padding, for example `left: 500, right: 0` it is expected that the resulting camera `center` would be more offset to account.
For example compare the resulting camera center in the two cases below, while the camera zoom changes to account for the padding, the center does not, but it should, resulting in the camera not respecting the padding.
```js
map.cameraForBounds(bounds, {
left: 500,
right: 0,
top: 0,
bottom: 0
}).center
map.cameraForBounds(bounds, {
left: 0,
right: 0,
top: 0,
bottom: 0
}).center
```
### Actual behavior
In v3.3.0 this was the case, but from v3.4.0 onwards adding `padding` to the `cameraForBounds` options affects the resulting camera `zoom`, but not the resulting camera `center`.
### Link to the demonstration
1. In v3.3.0 the following code produces this result, works as expected.
```js
const camera = map.cameraForBounds(bounds, {
padding: {
top: 10,
right: 10,
bottom: 10,
left: 10 + 400
}
});
map.easeTo({
center: camera.center,
zoom: camera.zoom,
bearing: camera.bearing
});
```
2. In v3.4.0, the same code produces this result, doesn't work as expected.
4. To obtain the same result as v3.3.0 when using v3.4.0 and later one needs to add an offset, like this
```js
const camera = map.cameraForBounds(bounds, {
padding: {
top: 10,
right: 10,
bottom: 10,
left: 10 + 400
},
offset: [ 400 / 2, 0 ]
});
map.easeTo({
center: camera.center,
zoom: camera.zoom,
bearing: camera.bearing
});
```
This is just a workaround, as you're applying an offset to correct it, but really an offset should offset it further.
full example, compare across v3.3.0 and v3.4.0
# full example
```html
Display a map on a webpage
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
#panel { position: absolute; top: 0; bottom: 0; width: 400px; background: rgba(0, 0, 255, 0.2);}
mapboxgl.accessToken = 'pk.ey...';
const bounds = [-71.08482, 43.08003225358635, -66.96466, 47.44777598732787 ];
const polygon = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-71.08482, 43.08003225358635],
[-66.96466, 43.08003225358635],
[-66.96466, 47.44777598732787],
[-71.08482, 47.44777598732787],
[-71.08482, 43.08003225358635]
]
]
}
};
const map = new mapboxgl.Map({
container: 'map',
devtools: true,
style: 'mapbox://styles/mapbox/streets-v9',
center: [-68.13734351262877, 45.137451890638886],
zoom: 5,
hash: false,
});
map.on('load', function() {
map.addLayer({
'id': 'bounds',
'type': 'line',
'source': {
'type': 'geojson',
'data': polygon
},
'layout': {},
'paint': {
'line-color': 'red',
'line-width': 2
}
});
const camera = map.cameraForBounds(bounds, {
padding: {
top: 10,
right: 10,
bottom: 10,
left: 10 + 400
},
// a workaround in 3.4.0 and later
//offset: [400 / 2, 0]
});
map.easeTo({
center: camera.center,
zoom: camera.zoom,
bearing: camera.bearing
});
});
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the cameraForBounds entry point and reproduce the supplied bounds and asymmetric-padding example across v3.3.0 and v3.4.0. Investigate how padding and offset affect the returned center, then add a regression test showing that the center accounts for asymmetric padding while the bounds still fit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- api, frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100