Skip to content

Instantly share code, notes, and snippets.

@mottaquikarim
Created June 11, 2017 15:32
Show Gist options
  • Select an option

  • Save mottaquikarim/437db4fa4a7efea14fb959689dca0c10 to your computer and use it in GitHub Desktop.

Select an option

Save mottaquikarim/437db4fa4a7efea14fb959689dca0c10 to your computer and use it in GitHub Desktop.
GMaps React Component
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;
}
}
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