rnmapbox / maps

A Mapbox react native module for creating custom maps
MIT License
2.28k stars 847 forks source link

[Bug]: Screen bounds wrong after setCamera with centre coordinates and padding #3663

Closed benjamin-sweney closed 1 month ago

benjamin-sweney commented 1 month ago

Mapbox Implementation

Mapbox

Mapbox Version

11.7.1

React Native Version

0.75.1

Platform

iOS

@rnmapbox/maps version

main

Standalone component to reproduce

import { Camera, MapView } from '@rnmapbox/maps';
import Mapbox from '@rnmapbox/maps';
import React, { useRef } from 'react';
import { Button, Text, StyleSheet, TouchableOpacity, View } from 'react-native';

const styles = StyleSheet.create({
  touchableContainer: { borderColor: 'black', borderWidth: 1.0, width: 60 },
  touchable: {
    backgroundColor: 'blue',
    width: 40,
    height: 40,
    borderRadius: 20,
    alignItems: 'center',
    justifyContent: 'center',
  },
  touchableText: {
    color: 'white',
    fontWeight: 'bold',
  },
  matchParent: { flex: 1 },
});

const AnnotationContent = ({ title }: { title: string }) => (
  <View style={styles.touchableContainer}>
    <Text>{title}</Text>
    <TouchableOpacity style={styles.touchable}>
      <Text style={styles.touchableText}>Btn</Text>
    </TouchableOpacity>
  </View>
);

const BugReportExample = () => {
  const cameraRef = useRef<Mapbox.Camera>(null);

  const onPress = () =>
    cameraRef.current?.setCamera({
      centerCoordinate: [-74.00597, 40.71427],
      padding: {
        paddingTop: 48,
        paddingLeft: 48,
        paddingRight: 48,
        paddingBottom: 480,
      },
      animationMode: 'flyTo',
      animationDuration: 250,
    });

  return (
    <>
      <Button title="Center on marker" onPress={onPress} />
      <MapView style={{ flex: 1 }}>
        <Camera
          ref={cameraRef}
          centerCoordinate={[-74.00597, 40.71427]}
          zoomLevel={14}
        />
        <Mapbox.MarkerView coordinate={[-74.00597, 40.71427]}>
          <AnnotationContent title={'this is a marker view'} />
        </Mapbox.MarkerView>
        <Mapbox.MarkerView coordinate={[-74.001097, 40.71527]}>
          <AnnotationContent title={'this is a marker view'} />
        </Mapbox.MarkerView>
      </MapView>
    </>
  );
};

export default BugReportExample;

Observed behavior and steps to reproduce

https://github.com/user-attachments/assets/a4eb8864-60b3-4e60-8a7a-fda3ed4771c1

After setting camera with a centre coordinate and padding the screen bounds are calculated incorrectly resulting in markers flickering in and out of view.

Expected behavior

Markers remain rendered while still within the screen bounds.

Notes / preliminary analysis

No response

Additional links and references

No response

mfazekas commented 1 month ago

@benjamin-sweney thanks I could repro the issue on maps v11. It seems to be more a padding issue than setCamera:

import { Camera, MapView } from '@rnmapbox/maps';
import Mapbox from '@rnmapbox/maps';
import React, { useRef } from 'react';
import { Button, Text, StyleSheet, TouchableOpacity, View } from 'react-native';

const styles = StyleSheet.create({
  touchableContainer: { borderColor: 'black', borderWidth: 1.0, width: 60 },
  touchable: {
    backgroundColor: 'blue',
    width: 40,
    height: 40,
    borderRadius: 20,
    alignItems: 'center',
    justifyContent: 'center',
  },
  touchableText: {
    color: 'white',
    fontWeight: 'bold',
  },
  matchParent: { flex: 1 },
});

const AnnotationContent = ({ title }) => (
  <View style={styles.touchableContainer}>
    <Text>{title}</Text>
    <TouchableOpacity style={styles.touchable}>
      <Text style={styles.touchableText}>Btn</Text>
    </TouchableOpacity>
  </View>
);

const BugReportExample = () => {
  const cameraRef = useRef(null);

  const onPress = () =>
    cameraRef.current?.setCamera({
      centerCoordinate: [-74.00597, 40.71427],
      padding: {
        paddingTop: 48,
        paddingLeft: 48,
        paddingRight: 48,
        paddingBottom: 480,
      },
      animationMode: 'flyTo',
      animationDuration: 250,
    });

  return (
    <>
      <Button title="Center on marker" onPress={onPress} />
      <MapView style={{ flex: 1 }}>
        <Camera
          ref={cameraRef}
          defaultSettings={{
            centerCoordinate: [-74.00597, 40.71427],
            zoomLevel: 10,
            padding: {
              paddingTop: 48,
              paddingRight: 48,
              paddingBottom: 480,
              paddingLeft: 48,
            },
          }}
        />
        <Mapbox.MarkerView coordinate={[-74.00597, 40.71427]}>
          <AnnotationContent title={'this is a marker view'} />
        </Mapbox.MarkerView>
        <Mapbox.MarkerView coordinate={[-74.001097, 40.71527]}>
          <AnnotationContent title={'this is a marker view'} />
        </Mapbox.MarkerView>
      </MapView>
    </>
  );
};

export default BugReportExample;