UNPKG

@appearhere/bloom

Version:

Appear Here's pattern library and styleguide

151 lines (127 loc) 3.29 kB
import PropTypes from 'prop-types'; import React, { Component } from 'react'; import cx from 'classnames'; import mapStyle from '!!file-loader!./mapStyle.json'; import mapboxgl from '../../utils/mapboxgl/mapboxgl'; import lngLat from '../../utils/propTypeValidations/lngLat'; import noop from '../../utils/noop'; import { DEFAULT_CENTER, DEFAULT_MAX_ZOOM, DEFAULT_ZOOM } from '../../constants/mapbox'; import css from './BaseMap.css'; import tile from './images/tile.jpg'; export default class BaseMap extends Component { static propTypes = { allowWrap: PropTypes.bool, center: lngLat, className: PropTypes.string, dragRotate: PropTypes.bool, mapClassName: PropTypes.string, mapboxStyle: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), maxZoom: PropTypes.number, onClick: PropTypes.func, onMapLoad: PropTypes.func, onMoveStart: PropTypes.func, onMoveEnd: PropTypes.func, zoom: PropTypes.number, }; static defaultProps = { allowWrap: true, center: DEFAULT_CENTER, dragRotate: false, mapboxStyle: mapStyle, maxZoom: DEFAULT_MAX_ZOOM, onClick: noop, onMapLoad: noop, onMoveStart: noop, onMoveEnd: noop, zoom: DEFAULT_ZOOM, }; componentDidMount() { const { allowWrap, center, dragRotate, mapboxStyle, maxZoom, onClick, onMapLoad, zoom, } = this.props; this.map = new mapboxgl.Map({ container: this.mapContainer, renderWorldCopies: allowWrap, style: mapboxStyle, center, dragRotate, maxZoom, zoom, }); this.map.on('click', onClick); this.map.on('movestart', this.handleMoveStart); this.map.on('moveend', this.handleMoveEnd); this.map.on('load', event => { onMapLoad(event.target); }); } componentWillUnmount() { const { onClick } = this.props; this.map.off('click', onClick); this.map.off('movestart', this.handleMoveStart); this.map.off('moveend', this.handleMoveEnd); this.map.remove(); } getMapboxGL() { return this.map; } setCenter = center => { this.map.setCenter(center, { user: false }); }; easeTo(options) { this.map.easeTo(options, { user: false }); } fitBounds(bounds, options) { this.map.fitBounds(bounds, options, { user: false }); } handleMoveEnd = data => { const { onMoveEnd } = this.props; const { user, ...rest } = data; const userAction = user !== false; onMoveEnd( userAction, { bounds: this.map.getBounds().toArray(), center: this.map.getCenter().toArray(), zoom: this.map.getZoom(), }, rest, ); }; handleMoveStart = e => { const { onMoveStart } = this.props; onMoveStart(e); }; zoomIn = () => { this.map.zoomIn(); }; zoomOut = () => { this.map.zoomOut(); }; mapboxgl = {}; render() { const { className, mapClassName } = this.props; return ( <div className={cx(css.root, className)} style={{ backgroundImage: `url(${tile})`, }} > <div ref={c => { this.mapContainer = c; }} className={cx(css.map, mapClassName)} /> </div> ); } }