Skip to content
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

Marker component always placed in top-left of map #44

Closed
mbrookes opened this issue Oct 8, 2015 · 16 comments
Closed

Marker component always placed in top-left of map #44

mbrookes opened this issue Oct 8, 2015 · 16 comments

Comments

@mbrookes
Copy link
Collaborator

mbrookes commented Oct 8, 2015

Not sure what I'm doing wrong, but my marker component (a material-icons icon) is being placed in the top left, regardless of the marker or map coordinates. It does then scroll with the map, but zooming the map makes the icon jump back to the corner.

(I also had to wrap the map in a fixed height div to get it to display within a flex container, otherwise it collapsed to 0 height, but that's a different issue.)

Here's my code:

SimpleMap = React.createClass({

  getDefaultProps: function() {
    return {
      center: {lat: 59.938043, lng: 30.337157},
      zoom: 12,
      greatPlaceCoords: {lat: 59.724465, lng: 30.080121}
    }
  },

  render() {
    return (
      <div style={{height: "400px", display: "-webkit-flex"}}>
      <GoogleMap
        defaultCenter={this.props.center}
        defaultZoom={this.props.zoom}>
        <i className="material-icons"
           lat={this.props.greatPlaceCoords.lat}
           lng={this.props.greatPlaceCoords.lng} >
          face</i>
      </GoogleMap>
      </div>
    );
  }
});

Any pointers appreciated. Thanks!

(React 0.13.x)

@istarkov
Copy link
Collaborator

istarkov commented Oct 8, 2015

What if you explicitly set width and remove display css prop
<div style={{height: "400px", width: "400px" }}>
?

Does window resize helps?

@mbrookes mbrookes changed the title Component placed in top-left of map regardless of coords. Marker component placed in top-left of map regardless of coords. Oct 8, 2015
@mbrookes mbrookes changed the title Marker component placed in top-left of map regardless of coords. Marker component always placed in top-left of map Oct 8, 2015
@mbrookes
Copy link
Collaborator Author

mbrookes commented Oct 8, 2015

Hi @istarkov, window resize followed by moving the map does reposition the icon.

I narrowed it down to being related to a css zoom animation applied to one of the outer components by <ReactCSSTransitionGroup>. The CSS is "borrowed" from animate.css. This uses transform: scale3d(.3, .3, .3) which I believe is the cause.

Is there perhaps a way to defer the marker placement until after the animation completes?

@istarkov
Copy link
Collaborator

istarkov commented Oct 8, 2015

This is because on the moment of GoogleMap component created, size of it's container is unknown or small (because of animation).
It's almost impossible in browser without periodic checks to get component size. So one solution is to create GoogleMap control after animation completes.

Other hack solution is to call via ref next method on GoogleMap:

googleMapRef_._setViewSize(); and modify center prop on small small delta.

example:

// CALL THIS TO REFRESH SIZE
refresh() {
   this.googleMapRef_._setViewSize();
  // mb will work without changing center 
  this.setState({
     center: {
       lat: this.state.center.lat + 0.000000001,
       lng: this.state.center.lng + 0.000000001,
      }, 
   });
}

render() {
  return (
    <GoogleMap ref={r => this.googleMapRef_ = r} 
      center={this.state.center} 
      defaultZoom={10}><Marker lat lng/>...
  );
}

@mbrookes
Copy link
Collaborator Author

mbrookes commented Oct 8, 2015

Thank you for your help!

@martingg88
Copy link

@istarkov. tried your given hack solution and don't think it will work if change the height of div container after resize.

@istarkov
Copy link
Collaborator

@martingg88 Why u think so?

@mbrookes Does this hack works for you?

@martingg88
Copy link

i tried it and it doesn't work..

it will work if i do not change height after resize.

@istarkov
Copy link
Collaborator

Provide source

@martingg88
Copy link

run the following function and then your hack solution in onresize event.

_performLayoutFrame: function(){
this.height = window.clientHeight;
this.width = window.clientWidth;
this.refs.map_container.style.width= (this.width) + 'px';
this.refs.map_container.style.height = (this.height) + 'px';
},

@istarkov
Copy link
Collaborator

In onresize event? Why?

@istarkov
Copy link
Collaborator

Also

this.height = window.clientHeight;
this.width = window.clientWidth;
this.refs.map_container.style.width= (this.width) + 'px';
this.refs.map_container.style.height = (this.height) + 'px';

Do u think this is react?

@martingg88
Copy link

i need to resize the container to fit into the visible screen when user resize the browser or rotate mobile device.

@istarkov
Copy link
Collaborator

  1. Never mutate Dom directly
  2. Call refresh NOT inside resize event handler (GoogleMap smart enough to do it)
  3. Call refresh after u changed size of above container. (ComponentDidUpdate is a good place for that)

@martingg88
Copy link

it won't work after try to follow your suggestion.
it will only work without change height dimension for container.

@istarkov
Copy link
Collaborator

I can't say anything without full component source

@leehart
Copy link

leehart commented Dec 4, 2015

The following is working for me, but seems very smelly. Any improvements?

  onResize : function() 
  {
    this._googleMapRef._setViewSize();

    if (this.state.maps && this.state.map)
    {
      let center =  this.state.map.getCenter();
      this.state.maps.event.trigger(this.state.map, 'resize');
      this.state.map.setCenter(center);
    }
  }
...
      <DetectResize onResize={this.onResize}>
        <GoogleMap
          center={center}
          zoom={zoom}
          yesIWantToUseGoogleMapApiInternals={true}
          onGoogleApiLoaded={({map, maps}) => this.setState({map: map, maps: maps})}
          options={getMapOptions}
          ref={r => this._googleMapRef = r}
        >
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants