|
<!DOCTYPE html> |
|
<html> |
|
|
|
<head> |
|
<meta charset="utf-8" /> |
|
<title>Mapbox Store Locator • Best Buy</title> |
|
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> |
|
<script src="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script> |
|
<link href="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" /> |
|
|
|
<script |
|
src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.min.js'></script> |
|
<link rel='stylesheet' |
|
href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.css' |
|
type='text/css' /> |
|
|
|
|
|
<link href='https://api.mapbox.com/mapbox-assembly/v0.24.0/assembly.min.css' rel='stylesheet'> |
|
<script async defer src='https://api.mapbox.com/mapbox-assembly/v0.24.0/assembly.js'></script> |
|
</head> |
|
|
|
<body> |
|
<script |
|
src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.0/mapbox-gl-directions.js"></script> |
|
<link rel="stylesheet" |
|
href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v4.1.0/mapbox-gl-directions.css" |
|
type="text/css" /> |
|
<style> |
|
.mapboxgl-popup { |
|
max-width: 500px; |
|
font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif; |
|
} |
|
|
|
.geocoder { |
|
position: absolute; |
|
z-index: 1; |
|
width: 50%; |
|
left: 50%; |
|
margin-left: -25%; |
|
top: 10px; |
|
} |
|
|
|
.mapboxgl-ctrl-geocoder { |
|
min-width: 100%; |
|
} |
|
|
|
.mapboxgl-ctrl-geocoder input[type='text'] { |
|
font-size: 12px; |
|
width: 100%; |
|
border: 0; |
|
background-color: transparent; |
|
height: 40px; |
|
margin: 0; |
|
color: rgba(0,0,0,.5); |
|
padding: 10px 40px 10px 30px; |
|
text-overflow: ellipsis; |
|
white-space: nowrap; |
|
overflow: hidden; |
|
} |
|
|
|
</style> |
|
|
|
<div class='flex-parent viewport-full relative scroll-hidden'> |
|
<div class='flex-child w-full w240-ml absolute static-ml left bottom'> |
|
<div class='flex-parent flex-parent--column viewport-third h-full hmax-full bg-white'> |
|
<div class='px12 py40'> |
|
<div class="col col 1"> |
|
<img src="64px-Best_Buy_logo_2018.svg.png" style="padding-bottom:20px;padding-top:10px"> |
|
</div> |
|
</div> |
|
<div class='flex-child flex-child--grow px12 py12 scroll-auto'> |
|
|
|
<div id='geocoder' class='geocoder'></div> |
|
<div id='feature-listing' class='listing'></div> |
|
|
|
</div> |
|
<footer class='px12 py12 bg-gray-faint txt-s'> |
|
<div class="col col 1"> |
|
<img width="100px" src="Black-Best-Buy.svg"> |
|
</div> |
|
</footer> |
|
</div> |
|
</div> |
|
<div id="map" class='flex-child flex-child--grow bg-darken10 viewport-twothirds viewport-full-ml'></div> |
|
</div> |
|
|
|
<script> |
|
mapboxgl.accessToken = 'pk.eyJ1IjoiaXZhbnJhbWlzY2FsIiwiYSI6ImNqdWU4dDdibjAwYW4zeXA4aHU1MzdmbmkifQ.DwHnMu8ee4P9ZnSwzFq2Xg'; |
|
var map = new mapboxgl.Map({ |
|
container: 'map', |
|
style: 'mapbox://styles/ivanramiscal/ckf689w102xww19mt6gfluopb', |
|
center: [-98, 38.88], |
|
maxZoom: 15, |
|
minZoom: 4, |
|
zoom: 4.46 |
|
}); |
|
|
|
var geocoder = new MapboxGeocoder({ |
|
accessToken: mapboxgl.accessToken, |
|
mapboxgl: mapboxgl |
|
}); |
|
|
|
document.getElementById('geocoder').appendChild(geocoder.onAdd(map)); |
|
|
|
// Holds visible visibleStores features for filtering |
|
var visibleStores = []; |
|
|
|
// Create a popup, but don't add it to the map yet. |
|
var popup = new mapboxgl.Popup({ |
|
closeButton: false, |
|
//className: 'col col--2 prose' |
|
}); |
|
|
|
//var filterEl = document.getElementById('feature-filter'); |
|
var listingEl = document.getElementById('feature-listing'); |
|
|
|
function renderListings(features) { |
|
// Clear any existing listings |
|
listingEl.innerHTML = ''; |
|
if (features.length) { |
|
features.forEach(function (feature) { |
|
var prop = feature.properties; |
|
|
|
var card = document.createElement('div'); |
|
|
|
var topline = document.createElement('h3'); |
|
topline.className += 'txt-h4 txt-bold pt18 mb12'; |
|
topline.textContent = prop.name |
|
|
|
card.appendChild(topline); |
|
card.className += 'col col--12 bg-darken10 px12 py12 mb12'; |
|
|
|
var item = document.createElement('a') |
|
item.href = feature.properties.Website; |
|
item.target = '_blank'; |
|
item.textContent = prop.Address; |
|
|
|
item.addEventListener('mouseover', function () { |
|
// Highlight corresponding feature on the map |
|
popup.setLngLat(feature.geometry.coordinates) |
|
//.setHTML( |
|
// '<a target="_blank" href="' + feature.properties.Website + '"><img width="50px" src="Black-Best-Buy.svg"><br><b>' + |
|
// feature.properties.name + '</b><img src="https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v11/static/' + feature.geometry.coordinates + ',16.93,0,60/300x200?access_token=' + mapboxgl.accessToken |
|
// + '"></a>' |
|
// ) |
|
.setHTML( |
|
'<img width="50px" src="Black-Best-Buy.svg"><br><b>' + |
|
feature.properties.name + '</b><img src="https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v11/static/' + feature.geometry.coordinates + ',16.93,0,60/300x200?access_token=' + mapboxgl.accessToken |
|
+ '">' |
|
) |
|
.addTo(map); |
|
}); |
|
|
|
card.appendChild(item); |
|
|
|
|
|
listingEl.appendChild(card); |
|
}); |
|
} |
|
} |
|
|
|
function normalize(string) { |
|
return string.trim().toLowerCase(); |
|
} |
|
|
|
function getUniqueFeatures(array, comparatorProperty) { |
|
var existingFeatureKeys = {}; |
|
// Because features come from tiled vector data, feature geometries may be split |
|
// or duplicated across tile boundaries and, as a result, features may appear |
|
// multiple times in query results. |
|
var uniqueFeatures = array.filter(function (el) { |
|
if (existingFeatureKeys[el.properties[comparatorProperty]]) { |
|
return false; |
|
} else { |
|
existingFeatureKeys[el.properties[comparatorProperty]] = true; |
|
return true; |
|
} |
|
}); |
|
|
|
return uniqueFeatures; |
|
} |
|
|
|
map.addControl( |
|
new MapboxDirections({ |
|
accessToken: mapboxgl.accessToken |
|
}), |
|
'top-right' |
|
); |
|
|
|
|
|
map.on('load', function () { |
|
map.addSource('stores', { //the store source, use in stores-viz |
|
'type': 'vector', |
|
'url': 'mapbox://ivanramiscal.alt70gam'//bestbuy |
|
|
|
}); |
|
|
|
map.addLayer({ |
|
'id': 'stores-viz', //use this in layers |
|
'type': 'circle', |
|
'source': 'stores', |
|
'source-layer': 'bestbuy-debh8z', //pull this from Tileset name |
|
'paint': { |
|
|
|
'circle-stroke-color': '#000', |
|
'circle-stroke-width': 0, |
|
'circle-radius': 5, |
|
'circle-color': 'rgba(255, 255, 255, 0)' |
|
|
|
} |
|
}) |
|
|
|
|
|
|
|
map.on('moveend', function () { |
|
var features = map.queryRenderedFeatures({ |
|
layers: ['stores-viz'] // |
|
}); |
|
|
|
console.log("Features " + features) |
|
|
|
if (features) { |
|
var uniqueFeatures = getUniqueFeatures(features, "name"); |
|
|
|
// Populate features for the listing overlay. |
|
renderListings(uniqueFeatures); |
|
|
|
// Clear the input container |
|
//filterEl.value = ''; |
|
|
|
// Store the current features in the `visibleStores` variable to |
|
// later use for filtering on `keyup`. |
|
visibleStores = uniqueFeatures; |
|
} |
|
}); |
|
|
|
|
|
map.on('mouseleave', 'stores-viz', function () { |
|
map.getCanvas().style.cursor = ''; |
|
popup.remove(); |
|
}); |
|
|
|
|
|
// Call this function on initialization |
|
// passing an empty array to render an empty state |
|
renderListings([]); |
|
|
|
|
|
|
|
}); |
|
|
|
</script> |
|
|
|
</body> |
|
|
|
</html> |