maps: setCamera doesn't take effect if followUserLocation set to true

Describe the bug setCamera doesn’t take effect if followUserLocation set to true

To Reproduce set Camera’s component followUserLocation prop to true and try to call setCamera on it’s ref

Example:

const MapView = (props) => {
  const resetRotation = useCallback(() => {
    camera.current?.setCamera({
      heading: 0,
      animationDuration: 200,
    });
  }, []);

  return (
    <MapboxGL.MapView>
      <MapboxGL.Camera
        ref={camera}
        followUserLocation
        followUserMode={'normal'}
      />
    </MapboxGL.MapView>
  );
};

Expected behavior it should be possible to setCamera or at least some of it’s props in case followUserLocation===true while i see there can be some conflict updating the coords (which one should be prioritized?) at least zoomLevel, pitch and rotation should be just fine

Screenshots

Versions (please complete the following information):

  • Platform:both ios and android
  • react-native-mapbox-gl 8.1.0-rc.4, 8.1.0-rc.6
  • React Native Version 0.62

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 6
  • Comments: 28 (13 by maintainers)

Most upvoted comments

@steffenkleinle If I may add another consideration about the workaround, you have to always make sure that the condition to perform the move/fly to coordinates is always correct, meaning that if you don’t want to flit, you have to make sure that in the https://github.com/rnmapbox/maps/issues/1079#issuecomment-1203964181 workaround the coordinates state variable is set to nil. I mean, I understand that this is a manageable thing, but it’s a needless complication. and as I said, I cannot even simply change the zoom level by using the camera api, despite changing the zoom would simply change this property, and not the camera center coordinate, meaning that the camera would still follow the user location, but the camera is totally immutable because of the current implementation, and this makes no sense, in my opinion.

Also experiencing this and a solution in the api would be much appreciated (something like the ignoreFollowUserLocation property on setCamera as proposed above). flyTo is also not doing anything if followUserLocation is set to true. The only solution we’ve come up so far is to set followUserLocation to false, listen in a useEffect on it and only then call setCamera such that one render happens in between and the state change kicks in:

  const [coordinates, setCoordinates] = useState<Coordinates>(null)
  const [followUserLocation, setFollowUserLocation] = useState<boolean>(true)

  const flyTo = (coordinates: Coordinates) => {
    setFollowUserLocation(false)
    setCoordinates(coordinates)
  }

  useEffect(() => {
    if (!followUserLocation && coordinates) {
      cameraRef.current.flyTo(coordinates)
    }
  }, [followUserLocation, coordinates])

  ...

The problem is that I start my application with the followUserLocation set to true, then the new coordinates for the current location arrive, but the camera doesn’t move on it’s own to the current location, and specifically with the desired zoom level, to say one example. This thing is not a problem on iOS, why should it be on Android? Have you tried removing any check over the followUserLocation value from the setCamera method implementation on the native side? Otherwise I might simply apply a patch on my own local project, but I don’t really know where to put my hands on, since I’m not that savvy about kotlin…so, any suggestion to allow me do what I would like to achieve would be good anyway.

@ferdicus Sorry for being unable to reply for such a long time, but this bug/feature had low prio for my project and I haven’t had enought time to dig into this in my free time… As a quick fix, I’ll try to implement the ignoreFollowUserLocation param, if it works fine for me, I’ll create a PR ASAP 😃 I’m still not sure whether this is proper solution though, but better than nothing, right?

as a workaround for not being able to use setCamera atm, did you see, that you could simply use these three, they would work for exactly the settings you’d like to edit @nasmuris :

Prop Type Default Required Description
followZoomLevel number none false The zoomLevel on map while followUserLocation is set to true
followPitch number none false The pitch on map while followUserLocation is set to true
followHeading number none false The heading on map while followUserLocation is set to true