如何在Google Map上使用HTML字符串或React组件更改标记图标?

时间:2019-11-26 12:09:32

标签: javascript reactjs google-maps google-maps-react

Marker.js

Celsius         Fahrenheit
--------------------------
0               32.00
1               33.80
2               35.60
3               37.40
4               39.20
5               41.00
6               42.80
7               44.60
8               46.40
9               48.20
10              50.00
11              51.80
12              53.60
13              55.40
14              57.20
15              59.00
16              60.80
17              62.60
18              64.40
19              66.20
20              68.00
21              69.80
22              71.60
23              73.40
24              75.20
25              77.00

HTML STRING或REACT COMPONENT

import React, {Fragment} from 'react'
import PropTypes from 'prop-types';

const camelize = function(str) {
    return str.split(' ').map(function(word) {
      return word.charAt(0).toUpperCase() + word.slice(1);
    }).join('');
}

const evtNames = [
  'click',
  'dblclick',
  'dragend',
  'mousedown',
  'mouseout',
  'mouseover',
  'mouseup',
  'recenter',
];

const wrappedPromise = function() {
    var wrappedPromise = {},
        promise = new Promise(function (resolve, reject) {
            wrappedPromise.resolve = resolve;
            wrappedPromise.reject = reject;
        });
    wrappedPromise.then = promise.then.bind(promise);
    wrappedPromise.catch = promise.catch.bind(promise);
    wrappedPromise.promise = promise;

    return wrappedPromise;
}

export class Marker extends React.Component {

  componentDidMount() {
    this.markerPromise = wrappedPromise();
    this.renderMarker();
  }

  componentDidUpdate(prevProps) {
    if ((this.props.map !== prevProps.map) ||
      (this.props.position !== prevProps.position) ||
      (this.props.html !== prevProps.html) ||
      (this.props.icon !== prevProps.icon)) {
        if (this.marker) {
            this.marker.setMap(null);
        }
        this.renderMarker();
    }
  }

  componentWillUnmount() {
    if (this.marker) {
      this.marker.setMap(null);
    }
  }

  renderMarker() {
    const {
      map,
      maps,
      position,
      mapCenter,
      icon,
      html,
      label,
      draggable,
      title,
      ...props
    } = this.props;
    if (!maps) {
      return null
    }

    let pos = position || mapCenter;

    if (!(pos instanceof maps.LatLng)) {
      pos = new maps.LatLng(pos.lat, pos.lng);
    }

    const pref = {
      map,
      position: pos,
      icon,
      label,
      title,
      draggable,
      ...props
    };
    this.marker = new maps.Marker(pref);

    evtNames.forEach(e => {
      this.marker.addListener(e, this.handleEvent(e));
    });

    this.markerPromise.resolve(this.marker);
  }

  getMarker() {
    return this.markerPromise;
  }

  handleEvent(evt) {
    return (e) => {
      const evtName = `on${camelize(evt)}`
      if (this.props[evtName]) {
        this.props[evtName](this.props, this.marker, e);
      }
    }
  }

  render() {
    return (
      <Fragment>
        {this.props.children && this.marker ?
          React.Children.only(
            React.cloneElement(
              this.props.children, 
              { marker: this.marker,
                maps: this.props.maps,
                map: this.props.map}
            )
          ) : null
        }
      </Fragment>
    )
  }
}

Marker.propTypes = {
  position: PropTypes.object,
  map: PropTypes.object
}

evtNames.forEach(e => Marker.propTypes[e] = PropTypes.func)

Marker.defaultProps = {
  name: 'Marker'
}

export default Marker;

标记组件,用于需要在Google地图上显示所有标记的另一个组件

<Tooltip title={shipment.shippingAddress.firstName + " " + shipment.shippingAddress.lastName + " " + shipment.shippingAddress.address1 + " / " + shipment.shippingAddress.address2}>
                      {
                        taskStatus === 'Assigned' ?
                        <div onClick={(e) => that.handelChangeMarkerClick()}>
                          <PlaceIcon style={{ width: 32, height: 32, color: mapMarkerColorsByStatus[taskStatus] }} />
                          {
                            selectedDriverFacility && selectedDriverFacility.id == inventoryFacility.id ? 
                            <span style={{padding: '3px', backgroundColor: '#FFF', borderRadius: '20px', display: 'block', textAlign:'center', fontSize: '12px', minWidth: '15px'}}>{counter}</span>
                            : null
                          }
                        </div> :
                        <div>
                          <PlaceIcon style={{ width: 32, height: 32, color: mapMarkerColorsByStatus[taskStatus] }} />
                        </div>
                      }  
                    </Tooltip>

因此在Marker Component中作为 icon 的道具上,我想将其设置为HTML STRING或React Component,以便可以在Google地图上获得自定义标记。

在这里,将import { renderToString } from 'react-dom/server'; import Marker from './Marker'; import GoogleMapReact from 'google-map-react'; render() { let { markers } = this.props; return(<GoogleMapReact bootstrapURLKeys={{ key: 'URL_keys_here' }} defaultCenter={this.props.mapConfig.center} defaultZoom={this.props.mapConfig.zoom} yesIWantToUseGoogleMapApiInternals={true} onGoogleApiLoaded={({ map, maps }) => { if (this.props.isClickedMarker) { this.handleApiLoaded(map, maps, this.props.markers); } this.setState({ map: map, maps: maps }); }} options={this.createMapOptions}> {((maps && map) && (markers && markers.length > 0)) ? markers.map((marker, index) => { return (<Marker icon={renderToString(marker.icon)} key={`index_${index}_${marker.location && marker.location[0]}_${marker.location && marker.location[1]}`} maps={this.state.maps} map={this.state.map} position={{ lat: marker.location && marker.location[0], lng:marker.location && marker.location[1]}} />); }): null} </GoogleMapReact> ); } 的值视为HTML STRING或REACT COMPONENT

0 个答案:

没有答案