maps
maps copied to clipboard
[Bug]: iOS topImage inconsistent rendering
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
same issue