mirror of
https://github.com/visgl/react-map-gl.git
synced 2026-01-25 16:02:50 +00:00
119 lines
2.6 KiB
JavaScript
119 lines
2.6 KiB
JavaScript
/* global window */
|
|
import React, {Component} from 'react';
|
|
import {render} from 'react-dom';
|
|
import MapGL, {Marker, Popup, NavigationControl} from 'react-map-gl';
|
|
|
|
import CityPin from './components/city-pin';
|
|
|
|
import CITIES from './data/cities.json';
|
|
|
|
import './app.css';
|
|
import 'mapbox-gl/dist/mapbox-gl.css';
|
|
|
|
const token = process.env.MAPBOX_ACCESS_TOKEN || // eslint-disable-line
|
|
'Set MAPBOX_ACCESS_TOKEN environment variable or put your token here.';
|
|
|
|
if (!token) {
|
|
throw new Error('Please specify a valid mapbox token');
|
|
}
|
|
|
|
class Root extends Component {
|
|
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
viewport: {
|
|
latitude: 37.785164,
|
|
longitude: -100,
|
|
zoom: 4,
|
|
bearing: 0,
|
|
pitch: 0,
|
|
},
|
|
width: 500,
|
|
height: 500,
|
|
popupInfo: null
|
|
};
|
|
|
|
this._updateViewport = this._updateViewport.bind(this);
|
|
this._resize = this._resize.bind(this);
|
|
this._renderCityMarker = this._renderCityMarker.bind(this);
|
|
}
|
|
|
|
componentDidMount() {
|
|
window.addEventListener('resize', this._resize);
|
|
this._resize();
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
window.removeEventListener('resize', this._resize);
|
|
}
|
|
|
|
_updateViewport(viewport) {
|
|
this.setState({viewport});
|
|
}
|
|
|
|
_resize() {
|
|
this.setState({
|
|
width: window.innerWidth,
|
|
height: window.innerHeight
|
|
});
|
|
}
|
|
|
|
_renderCityMarker(city, index) {
|
|
return (
|
|
<Marker key={`marker-${index}`}
|
|
longitude={city.longitude}
|
|
latitude={city.latitude} >
|
|
<CityPin size={20} onClick={() => this.setState({popupInfo: city})} />
|
|
</Marker>
|
|
);
|
|
}
|
|
|
|
_renderPopup() {
|
|
const {popupInfo} = this.state;
|
|
|
|
return popupInfo && (
|
|
<Popup tipSize={5}
|
|
anchor="top"
|
|
longitude={popupInfo.longitude}
|
|
latitude={popupInfo.latitude}
|
|
onClose={() => this.setState({popupInfo: null})} >
|
|
{popupInfo.cityName}
|
|
</Popup>
|
|
);
|
|
}
|
|
|
|
render() {
|
|
|
|
const {viewport, width, height} = this.state;
|
|
|
|
return (
|
|
<MapGL
|
|
{...viewport}
|
|
mapStyle="mapbox://styles/mapbox/dark-v9"
|
|
onChangeViewport={this._updateViewport}
|
|
preventStyleDiffing={false}
|
|
mapboxApiAccessToken={token}
|
|
perspectiveEnabled
|
|
width={width}
|
|
height={height}>
|
|
|
|
{ CITIES.map(this._renderCityMarker) }
|
|
|
|
{this._renderPopup()}
|
|
|
|
<div className="nav">
|
|
<NavigationControl onChangeViewport={this._updateViewport} />
|
|
</div>
|
|
|
|
</MapGL>
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
const root = document.createElement('div');
|
|
document.body.appendChild(root);
|
|
|
|
render(<Root />, root);
|