From 22b566b0dab72604cdffa15bedbeb98e98cec32e Mon Sep 17 00:00:00 2001 From: Norman Torres Date: Wed, 18 Jul 2018 19:22:53 -0500 Subject: [PATCH] Circle support --- src/components/Circle.js | 118 +++++++++++++++++++++++++++++++++++++++ src/index.js | 1 + 2 files changed, 119 insertions(+) create mode 100644 src/components/Circle.js diff --git a/src/components/Circle.js b/src/components/Circle.js new file mode 100644 index 00000000..761dccf9 --- /dev/null +++ b/src/components/Circle.js @@ -0,0 +1,118 @@ +import React from 'react' +import PropTypes from 'prop-types' + +import { camelize } from '../lib/String' +const evtNames = ['click', 'mouseover', '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 Circle extends React.Component { + + componentDidMount() { + this.circlePromise = wrappedPromise(); + this.renderCircle(); + } + + componentDidUpdate(prevProps) { + if ((this.props.map !== prevProps.map) || + (this.props.position !== prevProps.position)) { + if (this.circle) { + this.circle.setMap(null); + this.renderCircle(); + } + } + } + + componentWillUnmount() { + if (this.circle) { + this.circle.setMap(null); + } + } + + renderCircle() { + const { + map, + google, + positions, + strokeColor = "#FF0000", + strokeOpacity = 0.8, + strokeWeight = 2, + fillColor = "#FF0000", + fillOpacity = 0.35, + radius = 150, + ...props + } = this.props; + + if (!google) { + return null; + } + + const data = positions.map((pos) => { + return new google.maps.LatLng(pos.lat, pos.lng); + }); + + const pref = { + strokeColor, + strokeOpacity, + strokeWeight, + fillColor, + fillOpacity, + map, + radius, + ...props + }; + + this.circle = new google.maps.Circle(pref); + + this.circle.set('radius', radius === undefined ? 150 : radius); + + + evtNames.forEach(e => { + this.circle.addListener(e, this.handleEvent(e)); + }); + + this.circlePromise.resolve(this.circle); + } + + getCircle() { + return this.circlePromise; + } + + handleEvent(evt) { + return (e) => { + const evtName = `on${camelize(evt)}` + if (this.props[evtName]) { + this.props[evtName](this.props, this.circle, e); + } + } + } + + render() { + return null; + } +} + +Circle.propTypes = { + position: PropTypes.object, + map: PropTypes.object, + icon: PropTypes.string +} + +evtNames.forEach(e => Circle.propTypes[e] = PropTypes.func) + +Circle.defaultProps = { + name: 'Circle' +} + +export default Circle diff --git a/src/index.js b/src/index.js index 125c6df6..a4f413bb 100644 --- a/src/index.js +++ b/src/index.js @@ -48,6 +48,7 @@ export {InfoWindow} from './components/InfoWindow'; export {HeatMap} from './components/HeatMap'; export {Polygon} from './components/Polygon'; export {Polyline} from './components/Polyline'; +export {Circle} from './components/Circle'; export class Map extends React.Component { constructor(props) {