Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setCamera doesn't take effect if followUserLocation set to true #1079

Closed
mkraina opened this issue Oct 18, 2020 · 28 comments
Closed

setCamera doesn't take effect if followUserLocation set to true #1079

mkraina opened this issue Oct 18, 2020 · 28 comments
Labels
Discussion General discussions, asking for input from users enhancement New feature or request help wanted Extra attention is needed Needs: Author Feedback

Comments

@mkraina
Copy link
Contributor

mkraina commented Oct 18, 2020

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
@mkraina
Copy link
Contributor Author

mkraina commented Oct 18, 2020

inspecting the code i've found following

  _createStopConfig(config = {}, ignoreFollowUserLocation = false) {
    if (this.props.followUserLocation && !ignoreFollowUserLocation) {
      return null;
    }
    ...
  }

  setCamera(config = {}) {
    this._setCamera(config);
  }

  _setCamera(config = {}) {
    let cameraConfig = {};

    if (config.stops) {
      cameraConfig.stops = [];

      for (const stop of config.stops) {
        cameraConfig.stops.push(this._createStopConfig(stop));
      }
    } else {
      cameraConfig = this._createStopConfig(config);
    }

    this.refs.camera.setNativeProps({stop: cameraConfig});
  }

wouldn't it make sense to at least provide possibility to pass ignoreFollowUserLocation as the Camera.setCamera fc parameter?

@ferdicus
Copy link
Member

hey @nasmuris, sounds reasonable to me - would you be willing to open a PR for this?

@ferdicus ferdicus added Discussion General discussions, asking for input from users enhancement New feature or request Needs: Author Feedback labels Oct 30, 2020
@stale
Copy link

stale bot commented Dec 29, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix This will not be worked on label Dec 29, 2020
@stale stale bot closed this as completed Jan 9, 2021
@SethArchambault
Copy link

I'd say this is a particularly important feature right now because in order for UserLocation renderMode to be native on android, Camera followUserLocation must be true, but if followUserLocation is true, setCamera can't be used! Can we reopen?

@systemlevel
Copy link
Contributor

Right, I believe that is the current status on setCamera. I'm wondering if we can get it consistent with how the iOS version works?

@ferdicus
Copy link
Member

I'll reopen this - and yes, would be great if someone could take a jab at this.
I could try, however I can't make any promises to when it would be done

@ferdicus ferdicus reopened this Jan 29, 2021
@stale stale bot removed the wontfix This will not be worked on label Jan 29, 2021
@ferdicus
Copy link
Member

ferdicus commented Feb 19, 2021

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

@manarfalah
Copy link

manarfalah commented Mar 11, 2021

Same issue here, as a workaround could you please give an example how to use these attributes ?, I have navigation mode map which use followUserLocation, if user moved the map and clicked on center button I want to get back to current location. @ferdicus

@mzu
Copy link
Contributor

mzu commented Mar 11, 2021

I'd say this is a particularly important feature right now because in order for UserLocation renderMode to be native on android, Camera followUserLocation must be true, but if followUserLocation is true, setCamera can't be used! Can we reopen?

Not sure if this would help in your case, but I currently set followUserLocation back to false once the map style has been initialised. This way I can carry on setting custom Camera coordinates. Something like this:

import React, {useState, useEffect, useRef} from 'react';
import {Platform, View} from 'react-native';
import MapboxGL from '@react-native-mapbox-gl/maps';

...

export default function MapScreen(props) {
  const cameraRef = useRef();
  const [followUser, setFollowUser] = useState(Platform.OS === 'android');

  useEffect(() => {
    if (!followUser && cameraRef?.current) {
      cameraRef.current.moveTo([-3.0886, 54.539627], 300);
    }
  }, [followUser]);

  return (
    <View style={styles.container}>
      <MapboxGL.MapView
        style={styles.map}
        styleURL={STYLE_URL}
        onDidFinishLoadingStyle={() => {
          if (followUser) {
            // Required for Android heading indicator,
            // triggers effect to focus camera on init values
            setFollowUser(false);
          }
        }}>
        <MapboxGL.Camera
          ref={cameraRef}
          // native for Android, only works if followUserLocation set to true
          followUserLocation={followUser}
          zoomLevel={11}
          centerCoordinate={[-3.0886, 54.539627]}
          animationMode={'flyTo'}
          animationDuration={1900}
        />
        <MapboxGL.UserLocation
          visible={true}
          renderMode={'native'}
          // Android indicator set via androidRenderMode
          showsUserHeadingIndicator={Platform.OS === 'ios'}
          // native/android only render mode (compass: triangle with heading)
          androidRenderMode={'compass'}
        />
      </MapboxGL.MapView>
    </View>
  );
}

@ferdicus
Copy link
Member

Same issue here, as a workaround could you please give an example how to use these attributes ?, I have navigation mode map which use followUserLocation, if user moved the map and clicked on center button I want to get back to current location. @ferdicus

This is not an issue - please refer to the gitter chat/ stackoverflow or Discussions for usage advise

@ferdicus ferdicus added the help wanted Extra attention is needed label Mar 12, 2021
@mkraina
Copy link
Contributor Author

mkraina commented Mar 25, 2021

@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?

@gokugen
Copy link

gokugen commented May 12, 2021

Same problem here. I'm trying to change the pitch based on the navigation mode but the problem is that when the user location updates at the same time the camera's animation stops.
For example, if i change dynamically the navigation mode to "course" and the pitch to 50, the camera will start the animation to fit to the new pitch but if the user location updates at the same time then the camera's animation will instantly stop.

@bobokeke0
Copy link

This also seem to affect camera.flyTo as well as changing the centerCoordinate dynamically using a state. When followUserLocation is set to true, both dont work, but if false, it works fine.

@ferdicus
Copy link
Member

ferdicus commented Jun 4, 2021

@gokugen - did you try Camera => followPitch
@bobokeke0 - I mean, those two are exclusive, how should the camera follow the user position and at the same time center the coordinate to a specific location? You have to chose one

@gokugen
Copy link

gokugen commented Jun 4, 2021

@ferdicus yes even with followPitch there was a problem. I've simply resolved this by setting setFollowUserLocation to false then change the Pitch then reset it to true.

@stale
Copy link

stale bot commented Aug 10, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix This will not be worked on label Aug 10, 2021
@SethArchambault
Copy link

Hi stale bot, so in your mind, things without activity are fixed? Robots...

@stale stale bot removed the wontfix This will not be worked on label Aug 10, 2021
@stale
Copy link

stale bot commented Apr 19, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix This will not be worked on label Apr 19, 2022
@SethArchambault
Copy link

Activity is happening.

@stale stale bot removed the wontfix This will not be worked on label Apr 19, 2022
@bensonz
Copy link

bensonz commented Jul 4, 2022

is there a workaround for this yet? I can't have followUser but also flyTo?

@steffenkleinle
Copy link

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])

  ...

@danidaryaweesh
Copy link

Has anybody been able to find a solution to this issue? I’m having it on Android (only when targeting Android 12 for some reason). Same code working on iOS without issues even if followUserLocation is set to true.

My environment:
RN version: 0.68.4
Version of this library: 8.5.0

@roledxd
Copy link

roledxd commented Dec 2, 2022

Activity is happening

@whiteHatCip
Copy link
Contributor

I understand that you people might think that it doesn't make sense to allow a setCamera, moveTo or flyTo operation to be performed when the user wants the map to follow location, but there are a bunch of cases where you wanna change some camera properties without the need to turn off followUserLocation, just to turn it back on once the camera change has been performed.

Plus, on iOS, this is not happening, and PLEASE don't change that 😅. I mean, I might want to change the zoom, the pinch and other properties, and I cannot do anything like that without this on/off, which sucks because I need to trigger a rerender uselessly... Are you sure it makes sense to keep it that way?

@mfazekas
Copy link
Contributor

mfazekas commented Dec 12, 2022

@whiteHatCip But it's not clear how flyTo/moveTo etc. should behave when followLocation is true. If you want to use flyTo/moveTo just disable followLocation, why is it an issue?

Zoom, pitch etc can be changed with changing followZoomLevel and followPitch

@whiteHatCip
Copy link
Contributor

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.

@steffenkleinle
Copy link

steffenkleinle commented Dec 12, 2022

Agreeing with @whiteHatCip here. In order to achieve a moveTo if followUserLocation is set to true we have to use this workaround: #1079 (comment)
In our opinion this is a perfectly normal use case that is a little bit overly complicated to achieve.

@whiteHatCip
Copy link
Contributor

whiteHatCip commented Dec 12, 2022

@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 #1079 (comment) 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.

@rnmapbox rnmapbox locked and limited conversation to collaborators Apr 2, 2023
@mfazekas mfazekas converted this issue into discussion #2759 Apr 2, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Discussion General discussions, asking for input from users enhancement New feature or request help wanted Extra attention is needed Needs: Author Feedback
Projects
None yet
Development

No branches or pull requests