React-map-gl: Markers are not positioned properly when zooming

Created on 11 Jul 2019  路  12Comments  路  Source: visgl/react-map-gl

In my application, I have a list of users that have coords and they are shown in a map with markers. We have a list that when you select a user, it will zoom into that user and when you unselect, it will zoom out. I noticed that when I zoom out, the markers are now off, the top style on the markers is off, the left style is the same.

To see if it's my app, I tested using one of your examples so I choose the controls example from this repo. I edited the app.js to have this constructor:

  constructor(props) {
    super(props);
    this.state = {
      viewport: {
        latitude: 37.785164,
        longitude: -100,
        zoom: 3.5,
        bearing: 0,
        pitch: 0
      },
      popupInfo: null
    };

    window.test =() => {
      this.setState({
        ...this.state,
        viewport: {
          ...this.state.viewport,
          zoom: this.state.viewport.zoom === 5 ? 1 : 5
        }
      })
    }
  }

So now in the browser console, I can execute test() to toggle a zoom between 1 and 5. When it zooms out to 1, the markers are now much south of where they originally were.

But when I use the navigation controls and zoom in and out, the markers are located properly. So what is the difference? What should I be doing differently to zoom correctly (even if it's a hack of a way)?

All 12 comments

Facing the same problem. Markers are only positioned correctly if I am using the highest possible zoom factor. As soon as the zoom factor is lower, they are way off (to the east in my case). I am using the mouse-wheel to zoom out.

I'm facing the same issue. If the zoom value is small, the marker is way off. So there is no way to properly position a marker if the container size changes.

You need to declare a size and set this to your custom marker, style={{transform: translate(${-size / 2}px,${-size}px)}}
That style fixed the problem.

This is the link for a sample usage, https://github.com/uber/react-map-gl/blob/4.0-release/examples/controls/src/city-pin.js

The controls example I linked to and tested from this repo has that transform style. I did notice, you are linking to the 4.0-release branch and not master which the latest version right now is 5.0.7 so maybe a 4 vs 5 difference?

Here is link to the pin in master: https://github.com/uber/react-map-gl/blob/master/examples/controls/src/city-pin.js

I'm using the latest version and it's working. The height of the custom marker should be equal to the size you declare.

You need to declare a size and set this to your custom marker, style={{transform: translate(${-size / 2}px,${-size}px)}}

Thanks for the info. This actually worked for me - once I applied it to the marker image itself, not to the Marker component.

This is basically the same as

style={{transform: translate(-50%,-100%)}}

Don't know why they made it that complicated by calculating the heights directly. The % values can also be easily applied via regular CSS styles.

For a centered marker, however, this works better for me:

style={{transform: translate(-50%,-50%)}}

I once again tried the controls example as I described when I opened this issue. I added the window.test function and executed it twice and the markers are then in the Pacific Ocean. Do note, city-pin.js does have the transform style already:

transform: `translate(${-size / 2}px,${-size}px)`

I then also tried the percentage transform:

transform: `translate(-50%, -100%)`

And as expected, the markers are in the ocean again.

I'm trying not to talk about my app to not let anything in my app affect this, this is why I'm using an example.

@mitchellsimoens Which element did you apply the transform to? Maybe it would help if you'd at least post your JSX code here.

@derwaldgeist thank you for willing to take a look. As I mentioned, I'm using the controls example in this repo. Link to it here. In this example, the city-pin.js has the transform on the svg so the transform is on the pin image, not the marker.

To test the zooming in the same way I am doing in my app, I'm simply changing the zoom level and letting react update the props of the MapGL component. To edit the example, in app.js you can update the constructor to be:

  constructor(props) {
    super(props);
    this.state = {
      viewport: {
        latitude: 37.785164,
        longitude: -100,
        zoom: 3.5,
        bearing: 0,
        pitch: 0
      },
      popupInfo: null
    };

    window.test = () => {
      this.setState({
        ...this.state,
        viewport: {
          ...this.state.viewport,
          zoom: this.state.viewport.zoom === 5 ? 1 : 5
        }
      })
    }
  }

Then when you run the example, in the browser console you can execute test() once to zoom in, then execute it again to zoom out. When it zooms out, the pins are in the pacific ocean which is incorrect.

Ok, if the pin is on the image, it works for me (in my own app). So I dunno what happens on your end. (Haven't tested the samples in this repo, though.)

@mitchellsimoens I am unable to reproduce: https://codesandbox.io/embed/react-map-gl-markers-lthvo

Use offset would help. See #585

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sudoStatus200 picture sudoStatus200  路  5Comments

tomrussell picture tomrussell  路  5Comments

ckalas picture ckalas  路  5Comments

MattReimer picture MattReimer  路  3Comments

AriLFrankel picture AriLFrankel  路  3Comments