Zoom level not applied correctly when switching from setting camera with `centerCoordinate` to `bounds`
Nobody has claimed this yet.
- Dominant language
- Kotlin
- Stars
- 2.9k
- Forks
- 947
- Avg merge
- 6d 37m
- Merged PRs (30d)
- 1
Description
Mapbox Implementation
Mapbox
Mapbox Version
11.3.0
React Native Version
0.72.4
Platform
iOS, Android
@rnmapbox/maps version
10.1.19
Standalone component to reproduce
import React, { useRef } from "react";
import { Button, StyleSheet, TouchableOpacity, View, Text } from "react-native";
import Mapbox from "@rnmapbox/maps";
import { ShapeSource, CircleLayer, Camera } from "@rnmapbox/maps";
const App = () => {
const realMapRef = useRef<Mapbox.MapView>(null);
const realCameraRef = useRef<Mapbox.Camera>(null);
const currentZoom = 16;
const sheetHeight = 374;
const padding = {
paddingTop: 60,
paddingLeft: 24,
paddingRight: 24,
paddingBottom: sheetHeight ? sheetHeight - 30 : 30,
};
// this function is called in the parent component. Left for the reference
const zoomToBounds = (bounds) => {
realCameraRef.current.camera?.setCamera({
bounds: {
ne: [ 10.6701055, 59.9111846 ],
sw: [ 10.6270699, 59.9008117 ],
},
padding: padding,
heading: 0.0, // reset to north
animationMode: 'easeTo',
});
};
// this function is called in the parent component. Left for the reference
const zoomToPosition = (pos) => {
realCameraRef.current.setCamera({
centerCoordinate: [ 10.6701055, 59.9008117 ],
padding: padding,
zoomLevel: currentZoom < 17 ? 17 : undefined,
heading: 0.0,
animationMode: 'easeTo',
});
};
return (
<Mapbox.MapView
ref={realMapRef}
styleURL="mapbox://styles/123"
projection="globe"
rotateEnabled={true}
scaleBarEnabled={false}
logoEnabled={false}
>
<Camera ref={realCameraRef} animationDuration={0} />
{/*Rest of the code*/}
</Mapbox.MapView>
);
}
export default App;
Observed behavior and steps to reproduce
I see warning in Xcode when the bug happens: [Warning, maps-core]: {}[General]: Unable to calculate camera for given bounds/geometry, padding is greater than map's width or height.
We set the camera position and zoom level by using two methods, depends on what the user click.
If user click a marker in the map, we call zoomToPosition function where we set centerCoordinate with the marker position and the padding.
If user click on the fence we call zoomToBounds function where we use bounds param to set the camera in the center with the correct zoom.
The problem is that when we call zoomToPosition and the camera zoom in to the marker and later we call zoomToBounds the camera centers correctly but the zoom level is not applied to show all the markers within the bounds.
https://github.com/rnmapbox/maps/assets/13038459/ebb1df5a-201a-4501-b248-9e596c6d1563
const padding = {
paddingTop: topSafeArea + 10,
paddingLeft: 24,
paddingRight: 24,
paddingBottom: sheetHeight ? sheetHeight - 30 : 30,
};
const zoomToPosition = (pos) => {
realCameraRef.current.setCamera({
centerCoordinate: [ 10.6701055, 59.9008117 ],
padding: padding,
zoomLevel: currentZoom < 17 ? 17 : undefined,
heading: 0.0,
animationMode: 'easeTo',
});
};
const zoomToBounds = (bounds) => {
realCameraRef.current.camera?.setCamera({
bounds: {
ne: [ 10.6701055, 59.9111846 ],
sw: [ 10.6270699, 59.9008117 ],
},
padding: padding,
heading: 0.0, // reset to north
animationMode: 'easeTo',
});
};
Screen recording. Here we can see that clicking on the marker zoom in the camera, when we navigate back the zoomToBounds is called and it should zoom out the camera to show all the markers, but instead the zoom level don't change.
https://github.com/rnmapbox/maps/assets/13038459/bc2d5116-047d-49f7-b33b-d01ca54c2ae0
Expected behavior
Zoom level should be applied correctly to show all the markers within the bounds when calling first
camera?.setCamera({
centerCoordinate: pos,
padding: padding,
zoomLevel: currentZoom < 17 ? 17 : undefined,
heading: 0.0,
animationMode: 'easeTo',
});
and calling after that setCamera with bounds
realCameraRef.current.camera?.setCamera({
bounds: {
ne: [ 10.6701055, 59.9111846 ],
sw: [ 10.6270699, 59.9008117 ],
},
padding: padding,
heading: 0.0, // reset to north
animationMode: 'easeTo',
});
};
Zoom level is not applied correctly when we use
Notes / preliminary analysis
We render the bottom sheet on the map. We use the bottom sheet height to calculate bottom padding, to make sure we center the camera in the visible part of the map.
It appears that this zoom issue is gone when we set the padding to the static value example: 30, but this will not center the camera in the visible part of the map.
Additional links and references
No response
Related issue #3354
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 with the Camera.setCamera calls in the reproduction and compare bounds handling with the dynamically calculated bottom-sheet padding; review related issue #3354. Done means switching from centerCoordinate to bounds applies a zoom that displays all markers while preserving visible-map centering on both iOS and Android.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react-native, typescript
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100