UNPKG

@bewithjonam/mapboxgl-spiderifier

Version:

Spiderify markers on mapbox-gl using marker overlays.

195 lines (181 loc) 7.08 kB
<!DOCTYPE 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>