@bewithjonam/mapboxgl-spiderifier
Version:
Spiderify markers on mapbox-gl using marker overlays.
195 lines (181 loc) • 7.08 kB
HTML
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.28.0/mapbox-gl.css">
<link rel="stylesheet" type="text/css" href="../lib/mapboxgl-spiderifier.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.js"></script>
<script type="text/javascript" src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.28.0/mapbox-gl.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<script type="text/javascript" src="../lib/mapboxgl-spiderifier.js"></script>
<title>Mapbox gl spiderfier Custom markers</title>
<style type="text/css">
#map {
width: 100%;
height: 500px;
}
.spidered-marker .icon-div{
position: relative;
width: 40px;
height: 40px;
margin-left: -20px;
margin-top: -20px;
font-size: 20px;
}
.spidered-marker:not(:hover) .icon-div .circle-icon{
color: white;
}
.spidered-marker:hover .icon-div .type-icon{
color: white;
}
</style>
<script type="text/javascript">
window.onload=function(){
mapboxgl.accessToken = 'pk.eyJ1Ijoic29jcmF0YSIsImEiOiJjaXJxc2wzam0waGU5ZmZtODhqd2ttamdxIn0.1ZQEByXoDD7fGIa9lUHIqg';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-74.50, 40],
zoom: 7,
}),
spiderfier = new MapboxglSpiderfier(map, {
animate: true,
animationSpeed: 200,
onClick: function(e, marker){
console.log(marker);
},
initializeMarker: function(markerObject){
var markerElem = markerObject.elements.marker,
marker = markerObject.marker;
markerElem.className = markerElem.className + ' fa-stack fa-lg';
markerElem.innerHTML = '<i class="circle-icon fa fa-circle fa-stack-2x"></i>' +
'<i class="type-icon fa fa-' + marker.type + ' fa-stack-1x"></i>'
markerElem.style.color = marker.color;
$(markerElem)
.on('mouseenter', function(){
popupOverlay = createOverlay(markerObject);
popupOverlay.setHTML('Icon used is <b>fa-' + marker.type+'</b>')
.addTo(map)
markerObject.mapboxMarker.setPopup(popupOverlay);
})
.on('mouseleave', function(){
if(popupOverlay){
popupOverlay.remove();
}
});
}
}),
iconTypes = ['car', 'bicycle', 'bus', 'cab', 'truck', 'train', 'rocket', 'ship'],
iconColors = ['red', 'blue', 'green', 'orange', '#ab1234', '#112312'];
function randomMarker(index){
return {
id: index,
type: _.sample(iconTypes),
color: _.sample(iconColors)
}
};
function createOverlay(markerObject){
var offset = 10,
iconOffsetX = markerObject.spiderParam.x,
iconOffsetY = markerObject.spiderParam.y;
popupOverlay = new mapboxgl.Popup({
closeButton: true,
closeOnClick: false,
offset: {
'top': offsetVariant([0, offset], iconOffsetX, iconOffsetY),
'top-left': offsetVariant([offset,offset], iconOffsetX, iconOffsetY),
'top-right': offsetVariant([-offset,offset], iconOffsetX, iconOffsetY),
'bottom': offsetVariant([0, -offset], iconOffsetX, iconOffsetY),
'bottom-left': offsetVariant([offset, -offset], iconOffsetX, iconOffsetY),
'bottom-right': offsetVariant([-offset, -offset], iconOffsetX, iconOffsetY),
'left': offsetVariant([offset, -offset], iconOffsetX, iconOffsetY),
'right': offsetVariant([-offset, -offset], iconOffsetX, iconOffsetY)
}
});
return popupOverlay;
};
function offsetVariant(offset, variantX, variantY) {
return [offset[0]+ (variantX || 0), offset[1]+ (variantY || 0)];
}
map.on('style.load', function() {
map.addSource('circle', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{type: 'feature',
properties: {count: 6},
geometry: {
type: 'Point',
coordinates: [-74.50, 40]
}},
{type: 'feature',
properties: {count: 20},
geometry: {
type: 'Point',
coordinates: [-75.50, 40.5]
}},
{type: 'feature',
properties: {count: 50},
geometry: {
type: 'Point',
coordinates: [-76.0, 39.5]
}}
]
}
});
map.addLayer({
'id': 'circle',
'type': 'circle',
'source': 'circle',
'paint': {
'circle-radius': 30,
'circle-color': '#288DC1',
'circle-opacity': 0.8
},
});
map.on('mousemove', mouseMove);
map.on('click', mouseClick);
});
function mouseClick(e) {
var features = map.queryRenderedFeatures(e.point, {
layers: ['circle']
}),
numberOfSpiderifiedMarkers = _.random(5, 30),
markers;
if (!features.length) {
//remove old spiderfy
return;
} else {
count = features[0].properties.count
markers = _.map(_.range(count), randomMarker);
spiderfier.spiderfy(features[0].geometry.coordinates, markers);
}
}
function mouseMove(e) {
var features = map.queryRenderedFeatures(e.point, {
layers: ['circle']
});
map.getCanvas().style.cursor = (features.length) ? 'pointer' : '';
}
}
</script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">MapboxglSpiderifier</a>
</div>
</div>
</nav>
<div class="container" style="margin-top: 100px;">
<p>Click on any blue circle for spiderified markers. On every click, different number of markers will load.</p>
<div id="map"></div>
</div>
</body>
</html>