[Bug]: iOS topImage inconsistent rendering
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
default
React Native Version
0.71.8
Platform
iOS
@rnmapbox/maps version
10.1.19
Standalone component to reproduce
import React, { useRef, useEffect, useState } from 'react';
import Mapbox, { MapView, Camera, CustomLocationProvider, LocationPuck, Viewport } from '@rnmapbox/maps';
import { Icon } from 'react-native-elements';
export default function BugReportExample() {
const [style, setStyle] = useState('mapbox://styles/mapbox/streets-v11');
const [bearing, setBearing] = useState(0);
const [location, setLocation] = useState([-74.00597, 40.71427]);
const [prevLocation, setPrevLocation] = useState<number[] | null>(null);
const viewportRef = useRef<Viewport | null>(null);
// Bearing calculation function
function calculateBearing(lat1, lon1, lat2, lon2) {
const radLat1 = (lat1 * Math.PI) / 180;
const radLat2 = (lat2 * Math.PI) / 180;
const deltaLon = ((lon2 - lon1) * Math.PI) / 180;
const y = Math.sin(deltaLon) * Math.cos(radLat2);
const x = Math.cos(radLat1) * Math.sin(radLat2) - Math.sin(radLat1) * Math.cos(radLat2) * Math.cos(deltaLon);
const bearing = (Math.atan2(y, x) * 180) / Math.PI;
return (bearing + 360) % 360;
}
useEffect(() => {
const interval = setInterval(() => {
setLocation(location => {
// Calculate the bearing if prevLocation exists
if (prevLocation) {
const newBearing = calculateBearing(
prevLocation[1],
prevLocation[0],
location[1] + 0.0001,
location[0] + 0.0001
);
setBearing(newBearing);
}
const newLocation = [location[0] + 0.0001, location[1] + 0.0001];
// Update prevLocation with the current location before it changes
setPrevLocation(location);
return newLocation;
});
}, 500);
return () => clearInterval(interval);
}, [prevLocation]);
return (
<>
<MapView
style={{ flex: 1 }}
onDidFinishLoadingStyle={() => {
viewportRef.current?.transitionTo({ kind: 'followPuck' }, { kind: 'default' });
}}
styleURL={style}>
<Mapbox.Images
images={{
userLocationTopImage: "<path to image>",
}}
/>
<Camera
defaultSettings={{
centerCoordinate: [-74.00597, 40.71427],
zoomLevel: 14,
}}
followZoomLevel={14}
followUserLocation={true}
/>
<Viewport ref={viewportRef} />
<CustomLocationProvider coordinate={location} heading={bearing} />
<LocationPuck
visible={true}
puckBearingEnabled={true}
topImage={'userLocationTopImage'}
scale={['interpolate', ['linear'], ['zoom'], 10.0, 1.0, 20.0, 2.0]}
/>
</MapView>
<Icon
onPress={() => {
setStyle(
style === 'mapbox://styles/mapbox/streets-v11'
? 'mapbox://styles/mapbox/satellite-v9'
: 'mapbox://styles/mapbox/streets-v11'
);
}}
containerStyle={{
position: 'absolute',
bottom: 10,
right: 0,
}}
raised
name='layers'
type='material'
color={'black'}
/>
</>
);
}
Observed behavior and steps to reproduce
There is a bug with <LocationPuck />. It works perfectly fine on Android devices but on iOS the topImage is flipped on initial load. When I change the map style the image again flips and the scale is off.
iOS Device is on the left
Android Device is on the right
https://github.com/rnmapbox/maps/assets/17690783/8429d7df-3bd4-491a-9411-aa0b4c09b418
Expected behavior
No response
Notes / preliminary analysis
No response
Additional links and references
No response
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 standalone reproduction using MapView, Images, LocationPuck, and the styleURL changes, then trace the iOS handling of topImage during initial loading and style changes. Compare the iOS result with Android; done means the image orientation and scale remain correct on initial load and after switching styles.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, react-native, typescript
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100