Last active
October 7, 2018 12:39
-
-
Save erick-otenyo/c69b95706cdb1caf713add1b706b1f4a to your computer and use it in GitHub Desktop.
Make a mapbox gl circle layer blip (pulsate) - React JS
This file contains 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 from "react"; | |
import ReactMapboxGl, { Source, Layer } from "react-mapbox-gl"; | |
const Map = ReactMapboxGl({ | |
accessToken: "YOUR_ACCESS_TOKEN_HERE" | |
}); | |
class MapContainer extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
radius: 8, | |
initialOpacity: 1, | |
initialRadius: 8, | |
framesPerSecond: 15, | |
opacity: 1, | |
maxRadius: 18 | |
}; | |
} | |
onStyleLoad = m => { | |
this.map = m; | |
this.animateCircle(0); | |
}; | |
animateCircle = timestamp => { | |
setTimeout(() => { | |
requestAnimationFrame(this.animateCircle); | |
let { | |
radius, | |
opacity, | |
maxRadius, | |
framesPerSecond, | |
initialOpacity, | |
initialRadius | |
} = this.state; | |
radius += (maxRadius - radius) / framesPerSecond; | |
opacity -= 0.9 / framesPerSecond; | |
// mapbox gl will raise an error if opacity goes below 0 | |
if (opacity >= 0) { | |
this.map.setPaintProperty("point-blip", "circle-radius", radius); | |
this.map.setPaintProperty("point-blip", "circle-opacity", opacity); | |
} | |
// if opacity gets to zero, reset to initialRadius and initialOpacity | |
if (opacity <= 0) { | |
this.setState({ radius: initialRadius, opacity: initialOpacity }); | |
} else { | |
// update state with new radius and opacity | |
this.setState({ radius: radius, opacity: opacity }); | |
} | |
}, 1000 / this.state.framesPerSecond); | |
}; | |
// TODO: a rerender causes the map to reinitialize every time,thus resetting zoom and center to initials each time | |
// prevent rerender for now | |
shouldComponentUpdate() { | |
return false; | |
} | |
render() { | |
return ( | |
<Map | |
// eslint-disable-next-line | |
style="mapbox://styles/mapbox/light-v9" | |
containerStyle={{ height: "100%", width: "100%" }} | |
center={[0, 0]} | |
zoom={[13]} | |
onStyleLoad={this.onStyleLoad} | |
> | |
<Source | |
id="point" | |
geoJsonSource={{ | |
type: "geojson", | |
data: { | |
type: "Point", | |
coordinates: [0, 0] | |
} | |
}} | |
/> | |
<Layer | |
id="point-blip" | |
type="circle" | |
sourceId="point" | |
paint={{ | |
"circle-radius": this.state.initialRadius, | |
"circle-radius-transition": { duration: 0 }, | |
"circle-opacity-transition": { duration: 0 }, | |
"circle-color": "#007cbf" | |
}} | |
/> | |
<Layer | |
id="point" | |
type="circle" | |
sourceId="point" | |
paint={{ | |
"circle-radius": this.state.initialRadius, | |
"circle-color": "#007cbf" | |
}} | |
/> | |
</Map> | |
); | |
} | |
} | |
export default MapContainer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment