react-component-google-maps
Version:
A React Google Maps Component
321 lines (278 loc) • 10.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.GoogleMap = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _google = require('google');
var _google2 = _interopRequireDefault(_google);
var _Marker = require('./Marker');
var _Marker2 = _interopRequireDefault(_Marker);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // core modules
var GoogleMap = exports.GoogleMap = function (_Component) {
_inherits(GoogleMap, _Component);
function GoogleMap(props) {
_classCallCheck(this, GoogleMap);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(GoogleMap).call(this, props));
_this._directionsService = null;
_this._map = null;
_this._trafficLayer = null;
_this._mapMarkers = {};
_this._directionsData = [];
_this._setDirectionsData = function (directionsPolylines) {
_this._directionsData = directionsPolylines;
};
_this.panTo = function (msg, latLng) {
_this._map.panTo(latLng);
};
if (!_google2.default || !_google2.default.maps) {
throw 'Can\'t find Google Maps API';
}
_this._directionsService = new _google2.default.maps.DirectionsService();
_this._trafficLayer = new _google2.default.maps.TrafficLayer();
return _this;
}
_createClass(GoogleMap, [{
key: 'mapOptions',
value: function mapOptions() {
var _props = this.props;
var center = _props.center;
var mapOptions = _props.mapOptions;
var zoom = _props.zoom;
if (center) {
mapOptions.center = center;
}
if (zoom) {
mapOptions.zoom = zoom;
}
return mapOptions;
}
}, {
key: 'showMarkers',
value: function showMarkers() {
this.clearMarkers();
var map = this._map;
this._mapMarkers = this.props.markers.reduce(function (reduction, marker) {
reduction[marker.id] = new _google2.default.maps.Marker({
label: marker.label,
map: map,
position: marker.position,
title: marker.title
});
if (marker.icon) {
reduction[marker.id].setIcon(marker.icon);
}
return reduction;
}, {});
}
}, {
key: 'clearMarkers',
value: function clearMarkers() {
var markerKeys = Object.keys(this._mapMarkers);
var mapMarkers = this._mapMarkers;
markerKeys.forEach(function (markerKey) {
mapMarkers[markerKey].setMap(null);
delete mapMarkers[markerKey];
});
}
}, {
key: 'showTraffic',
value: function showTraffic() {
this._trafficLayer.setMap(this._map);
}
}, {
key: 'hideTraffic',
value: function hideTraffic() {
this._trafficLayer.setMap(null);
}
}, {
key: 'showDirections',
value: function showDirections() {
var _props$directionsMark = this.props.directionsMarkers;
var origin = _props$directionsMark.origin;
var destination = _props$directionsMark.destination;
var waypoints = _props$directionsMark.waypoints;
var _setDirectionsData = this._setDirectionsData;
var map = this._map;
this._directionsService.route({
origin: origin.position,
destination: destination.position,
waypoints: waypoints.map(function (waypoint) {
return { location: waypoint.position, stopover: true };
}),
optimizeWaypoints: true,
travelMode: _google2.default.maps.TravelMode.DRIVING,
provideRouteAlternatives: true
}, function (result, status) {
if (status == _google2.default.maps.DirectionsStatus.OK) {
var directionsData = result.routes[0].legs.map(function (leg) {
var polyline = new _google2.default.maps.Polyline({
path: [],
strokeColor: 'blue',
strokeWeight: 10,
strokeOpacity: 0.5
});
var infoWindow = new _google2.default.maps.InfoWindow({
content: leg.distance.text + '<br/>' + leg.duration.text
});
polyline.addListener('mouseover', function directionsRouteMouseoverEventHandler(e) {
this.setOptions({
strokeColor: 'red',
strokeOpacity: 0.5,
strokeWeight: 10
});
infoWindow.setPosition(e.latLng);
infoWindow.open(map);
});
polyline.addListener('mouseout', function directionsRouteMouseoutEventHandler() {
this.setOptions({
strokeColor: 'blue',
strokeWeight: 10,
strokeOpacity: 0.5
});
infoWindow.close();
});
var steps = leg.steps;
steps.forEach(function (step) {
step.path.forEach(function (latLng) {
polyline.getPath().push(latLng);
});
});
return {
infoWindow: infoWindow,
polyline: polyline
};
});
directionsData.forEach(function (leg) {
leg.polyline.setMap(map);
});
_setDirectionsData(directionsData);
}
});
}
}, {
key: 'hideDirections',
value: function hideDirections() {
this._directionsData.forEach(function (leg) {
leg.polyline.setMap(null);
_google2.default.maps.event.clearInstanceListeners(leg);
leg.infoWindow.close();
});
this._directionsData = [];
}
}, {
key: 'initializeMap',
value: function initializeMap() {
var _props2 = this.props;
var showDirections = _props2.showDirections;
var showTraffic = _props2.showTraffic;
// create a new google map
this._map = new _google2.default.maps.Map(_reactDom2.default.findDOMNode(this), this.mapOptions());
this.showMarkers();
// show traffic layer if props say so
if (showTraffic) {
this.showTraffic();
}
if (showDirections) {
this.showDirections();
}
this.props.subscribePanTo(this.panTo);
}
}, {
key: 'updateMap',
value: function updateMap(prevProps) {
var _props3 = this.props;
var showDirections = _props3.showDirections;
var showTraffic = _props3.showTraffic;
this._map.setOptions(this.mapOptions());
this.showMarkers();
if (showTraffic && !prevProps.showTraffic) {
this.showTraffic();
} else if (!showTraffic && prevProps.showTraffic) {
this.hideTraffic();
}
if (showDirections && !prevProps.showDirections) {
this.showDirections();
} else if (!showDirections && prevProps.showDirections) {
this.hideDirections();
}
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
this.initializeMap();
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps, prevState) {
this.updateMap(prevProps);
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.props.unsubscribePanTo(this.panTo);
}
}, {
key: 'render',
value: function render() {
var containerStyle = this.props.containerStyle;
return _react2.default.createElement(
'div',
{ style: containerStyle },
'Map'
);
}
}]);
return GoogleMap;
}(_react.Component);
GoogleMap.propTypes = {
center: _react.PropTypes.shape({
lat: _react.PropTypes.number,
lng: _react.PropTypes.number
}),
containerStyle: _react.PropTypes.object,
directionMarkers: _react.PropTypes.shape({
origin: _react.PropTypes.oneOfType([_react.PropTypes.object, _react.PropTypes.instanceOf(_Marker2.default)]),
destination: _react.PropTypes.oneOfType([_react.PropTypes.object, _react.PropTypes.instanceOf(_Marker2.default)]),
waypoints: _react.PropTypes.arrayOf(_react.PropTypes.oneOfType([_react.PropTypes.object, _react.PropTypes.instanceOf(_Marker2.default)]))
}),
mapOptions: _react.PropTypes.object,
markers: _react.PropTypes.arrayOf(_react.PropTypes.oneOfType([_react.PropTypes.object, _react.PropTypes.instanceOf(_Marker2.default)])),
subscribePanTo: _react.PropTypes.func,
unsubscribePanTo: _react.PropTypes.func,
zoom: _react.PropTypes.number,
showDirections: _react.PropTypes.bool,
showTraffic: _react.PropTypes.bool
};
GoogleMap.defaultProps = {
containerStyle: {
width: '100%',
height: '100%'
},
directionsMarkers: {
origin: null,
destination: null,
waypoints: []
},
mapOptions: {
center: {
lat: 30.3074625,
lng: -98.0335911
},
mapTypeControl: false,
streetViewControl: false,
zoom: 10
},
markers: [],
subscribePanTo: function subscribePanTo() {},
unsubscribePanTo: function unsubscribePanTo() {},
showDirections: false,
showTraffic: false
};