Created
June 11, 2017 15:32
-
-
Save mottaquikarim/437db4fa4a7efea14fb959689dca0c10 to your computer and use it in GitHub Desktop.
GMaps React Component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { Component } from 'react'; | |
| import ReactDOM from 'react-dom'; | |
| const generateRandomFunc = (functionRoot, cb = function(){}) => { | |
| const functionName = `${functionRoot}_${Date.now()}`; | |
| window[functionName] = (overrideCb = null) => { | |
| delete window[functionName]; | |
| if (overrideCb) { | |
| overrideCb(); | |
| return; | |
| } | |
| cb(); | |
| } | |
| return functionName; | |
| }; | |
| const paramify = params => Object.keys(params) | |
| .map(key => [key, params[key]].join('=')) | |
| .join('&'); | |
| const loadGMapScript = (url, params) => { | |
| return new Promise((resolve, reject) => { | |
| const functionName = generateRandomFunc('gmapsCallback', () => { | |
| resolve(true) | |
| }); | |
| params = Object.assign({}, params, { | |
| callback: functionName | |
| }); | |
| const script = document.createElement('script'); | |
| script.onload = () => window[functionName]; | |
| script.onerror = (e) => window[functionName](() => { | |
| reject(e); | |
| }); | |
| script.type = 'text/javascript'; | |
| script.src = url + '?' + paramify(params); | |
| document.body.appendChild( script ); | |
| }); | |
| } | |
| const loadMap = (domNode, options = {}) => new google.maps.Map(domNode, Object.assign({ | |
| zoom: 4, | |
| }, options)); | |
| export default class GMaps extends Component { | |
| state = { | |
| mapLoaded: false, | |
| mapUrl: 'https://maps.googleapis.com/maps/api/js', | |
| } | |
| _wrapStyle = { | |
| position: 'relative', | |
| width : "100%", | |
| height : "600px", | |
| } | |
| _shimStyle = { | |
| position: 'absolute', | |
| height: '100%', | |
| width: '100%', | |
| top: 0, | |
| left: 0, | |
| zIndex: 2, | |
| cursor: 'wait', | |
| } | |
| _loadMap() { | |
| const {mapUrl} = this.state; | |
| const {center, apiKey} = this.props; | |
| loadGMapScript(mapUrl, {key: apiKey}) | |
| .then(_ => this.map = loadMap(this.refs.map, { | |
| center, | |
| })) | |
| .then(_ => this.setState({ | |
| mapLoaded: true, | |
| })) | |
| } | |
| _initShimLogic() { | |
| const root = ReactDOM.findDOMNode(this.refs.root); | |
| const node = ReactDOM.findDOMNode(this.refs.shim); | |
| let timeout = null; | |
| root.addEventListener('mouseenter', () => { | |
| clearTimeout(timeout) | |
| timeout = setTimeout(() => { | |
| node.style.zIndex = -1; | |
| node.style.cursor = 'initial'; | |
| }, 2000) | |
| }); | |
| root.addEventListener('mouseleave', () => { | |
| clearTimeout(timeout) | |
| node.style.zIndex = 2; | |
| node.style.cursor = 'wait'; | |
| }); | |
| } | |
| componentDidMount() { | |
| this._loadMap(); | |
| this._initShimLogic(); | |
| } | |
| render() { | |
| const {_wrapStyle, _shimStyle} = this; | |
| return (<div ref="root" style={_wrapStyle}> | |
| <div ref="shim" style={_shimStyle}></div> | |
| <div id="droneMap" ref="map" style={_wrapStyle}></div> | |
| {this.renderMarkers()} | |
| </div>); | |
| } | |
| renderMarkers() { | |
| const {mapLoaded} = this.state; | |
| if (!mapLoaded) return null; | |
| const {children} = this.props; | |
| const {Children, cloneElement} = React; | |
| return Children.map(children, (child) => cloneElement(child, { | |
| mapLoaded: true, | |
| map: this.map, | |
| })) | |
| } | |
| } | |
| export class Marker extends Component { | |
| marker = null | |
| _loadMarker(props) { | |
| const {position, map, animation} = props; | |
| if (!map) return; | |
| this.marker = new google.maps.Marker({ | |
| position, | |
| map, | |
| animation: google.maps.Animation[animation] | |
| }); | |
| } | |
| componentDidMount() { | |
| this._loadMarker(this.props); | |
| } | |
| componentWillReceiveProps(nextProps) { | |
| this._loadMarker(nextProps) | |
| } | |
| render() { | |
| return null; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { Component } from 'react'; | |
| import GMaps, { Marker } from './GMaps'; | |
| export default class App extends Component { | |
| constructor(props){ | |
| super(props) | |
| } | |
| componentDidMount(){ | |
| } | |
| componentWillReceiveProps(){ | |
| } | |
| render() { | |
| return (<GMaps {...this.props} apiKey={"AIzaSyCgnmah1dhhXHZBFOj4z3CTuGxaatp0htE"} center={{ lat: 35.996023, lng: 36.784644 }}> | |
| <Marker position={{lat: 35.996023, lng: 36.784644}} animation="DROP" /> | |
| <Marker position={{lat: 30.996023, lng: 36.784644}} animation="DROP" /> | |
| </GMaps>); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment