简体   繁体   English

react-google-maps将地图缩放为圆形

[英]react-google-maps zoom map to circle

This is mainly a question about 'translating' JS to JSX. 这主要是关于将JS翻译成JSX的问题。

I have a react-google-maps map which contains a marker, and a circle around that marker: 我有一个react-google-maps地图,其中包含一个标记,以及围绕该标记的圆圈:

The Map component: 地图组件:

export class Map extends Component {
  render() {
    const GoogleMapInstance = withGoogleMap(props => (
      <GoogleMap
        defaultCenter = { { lat: parseFloat(this.props.lat), lng: parseFloat(this.props.lng) } }
        defaultZoom = { 16 }
        defaultOptions={{ styles: mapStyles }}
      >
        <Marker position={{ lat: parseFloat(this.props.lat), lng: parseFloat(this.props.lng) }}/>
        <Circle center={{ lat: parseFloat(this.props.lat), lng: parseFloat(this.props.lng) }} radius={parseFloat(this.props.accuracy)} options={{ fillColor: 'red', strokeColor: 'red' }}/>
      </GoogleMap>
    ))
    return (
      <div>
        <GoogleMapInstance
          containerElement={ <div style={{ height: '600px', width: '100%' }}/> }
          mapElement={ <div style={{ height: '100%' }}/> }
        />
      </div>
    )
  }
}

I would like the map to be zoomed such that the circle takes up about 50% of the map. 我想要缩放地图,使圆圈占地图的50%左右。 I understand using the Javascript API, I can just do: 我理解使用Javascript API,我可以这样做:

map.fitBounds(circle.getBounds())

But I'm not sure how to integrate that with the JSX that I have... 但是我不确定如何将它与我拥有的JSX集成......

You probably want to do something like this: 你可能想做这样的事情:

export class Map extends Component {
  constructor(props) {
    super(props)
    this.map = React.createRef()
    this.circle = React.createRef()
  }

  componentDidMount() {
    if (this.map && this.circle) {
      const bounds = this.circle.current.getBounds()
      this.map.current.fitBounds(bounds)
    }
  }

  render() {
    const GoogleMapInstance = withGoogleMap(props => (
      <GoogleMap
        defaultCenter = { { lat: parseFloat(this.props.lat), lng: parseFloat(this.props.lng) } }
        defaultZoom = { 16 }
        defaultOptions={{ styles: mapStyles }}
        ref={this.map}
      >
        <Marker position={{ lat: parseFloat(this.props.lat), lng: parseFloat(this.props.lng) }}/>
        <Circle ref={this.circle} center={{ lat: parseFloat(this.props.lat), lng: parseFloat(this.props.lng) }} radius={parseFloat(this.props.accuracy)} options={{ fillColor: 'red', strokeColor: 'red' }}/>
      </GoogleMap>
    ))
    return (
      <div>
        <GoogleMapInstance
          containerElement={ <div style={{ height: '600px', width: '100%' }}/> }
          mapElement={ <div style={{ height: '100%' }}/> }
        />
      </div>
    )
  }
}

The refs create a way to access the GoogleMap and Circle nodes, and the componentDidMount is a lifecycle hook that lets you run the fitBounds call when the Map component is first rendered to the DOM. refs创建了一种访问GoogleMapCircle节点的方法, componentDidMount是一个生命周期钩子,允许您在Map组件首次呈现给DOM时运行fitBounds调用。

Indeed, you could access native Google Map and Circle objects via Ref and manipulate it. 实际上,您可以通过Ref访问本机Google Map和Circle对象并进行操作。 But when it comes to getting map instance, prefer Map idle event over componentDidMount() lifecycle method to guarantee the map is ready, for example: 但是当涉及到获取地图实例时,更喜欢Map idle事件而不是componentDidMount()生命周期方法来保证地图准备就绪,例如:

handleMapIdle() {
   const map = this.map.current; //get Google Map instance
   //...
}

where 哪里

 <GoogleMap
        ref={this.map}
        onIdle={this.handleMapIdle}
        ...
      >
      ...
 </GoogleMap>

Here is a modified Map component: 这是一个修改过的Map组件:

class Map extends Component {
  constructor(props) {
    super(props);
    this.map = React.createRef();
    this.circle = React.createRef();
    this.handleMapIdle = this.handleMapIdle.bind(this);
    this.idleCalled = false;
  }

  handleMapIdle() {
    if (!this.idleCalled) {
      const bounds = this.circle.current.getBounds();
      this.map.current.fitBounds(bounds);
      this.idleCalled = true;
    }
  }

  render() {
    const GoogleMapInstance = withGoogleMap(props => (
      <GoogleMap
        ref={this.map}
        defaultCenter={{
          lat: parseFloat(this.props.lat),
          lng: parseFloat(this.props.lng)
        }}
        defaultZoom={this.props.zoom}
        onIdle={this.handleMapIdle}
      >
        <Marker
          position={{
            lat: parseFloat(this.props.lat),
            lng: parseFloat(this.props.lng)
          }}
        />
        <Circle
          ref={this.circle}
          center={{
            lat: parseFloat(this.props.lat),
            lng: parseFloat(this.props.lng)
          }}
          radius={parseFloat(this.props.accuracy)}
          options={{ fillColor: "red", strokeColor: "red" }}
        />
      </GoogleMap>
    ));
    return (
      <div>
        <GoogleMapInstance
          containerElement={<div style={{ height: "600px", width: "100%" }} />}
          mapElement={<div style={{ height: "100%" }} />}
        />
      </div>
    );
  }
}

Demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM