Skip to content

Instantly share code, notes, and snippets.

@lemwerks
Last active September 20, 2019 03:33
Show Gist options
  • Save lemwerks/ca90e06e3308431542589633a210c5a9 to your computer and use it in GitHub Desktop.
Save lemwerks/ca90e06e3308431542589633a210c5a9 to your computer and use it in GitHub Desktop.
by-the-way-demo
var config = {
style: 'mapbox://styles/lemwerks/ck0rioarv09sn1cpkjgoj1rna',
accessToken: 'pk.eyJ1IjoibGVtd2Vya3MiLCJhIjoiY2p1ZTRoYnd1MGxpNTQ0cjE0Mjl1cHRrYiJ9.kU435578KS5vrCHNwZX2kA',
showMarkers: true,
alignment: 'left',
mapStart: {
center: [-77.07567, 38.89583],
zoom: 11.23,
pitch: 60.00,
bearing: 43.61
},
chapters: [
{
id: 'intro',
title: 'A local’s guide to Washington, D.C',
image: 'https://www.washingtonpost.com/resizer/LB5cSvyCfPBXonvYBbgQq6OF8XQ=/1024x0/arc-anglerfish-washpost-prod-washpost.s3.amazonaws.com/public/3AB7DBUBM4I6TNMF4NVRNJJRVI.jpg',
description: 'To know Washington is to peel back its suit: The briefcases and blazers the rest of the world sees are just covers for a vibrant, creative community. Whether it’s the food scene — one of the country’s best — or murals tucked away in historic alleys, the city D.C. residents know is quirky — and inspiring.',
location: {
center: [-77.07567, 38.89583],
zoom: 11.23,
pitch: 60.00,
bearing: 43.61
},
onChapterEnter: [
// {
// layer: 'layer-name',
// opacity: 1
// }
],
onChapterExit: [
// {
// layer: 'layer-name',
// opacity: 0
// }
]
},
{
id: 'H Street',
title: 'H Street Corridor',
image: 'https://www.washingtonpost.com/resizer/MbNSpJZAb3cvD6ss6-C3os0c4co=/1024x0/arc-anglerfish-washpost-prod-washpost.s3.amazonaws.com/public/3WS2FSUDZUI6TNMF4NVRNJJRVI.jpg',
description: 'H Street NE is where native Washingtonians mingle with transplants over a beer or two (or three or four). You can experience chicken curry ramen at Toki Underground, a concert at Rock & Roll Hotel, late-night chess pie at Dangerously Delicious Pies and a nightcap on an outdoor patio at Hill Prince. Then you’ll be ready to stumble back to your Airbnb in a historic rowhouse just off the main drag.',
location: {
center: [-76.98696, 38.90020],
zoom: 16.00,
pitch: 60.00,
bearing: -50.37
},
onChapterEnter: [],
onChapterExit: []
},
{
id: 'Capitol Hill/Hill East',
title: 'Capitol Hill/Hill East',
image: 'https://www.washingtonpost.com/resizer/muqEeFFiBZS7ea5Ku9r7PgbjQXM=/1024x0/arc-anglerfish-washpost-prod-washpost.s3.amazonaws.com/public/2KSPZ7UDZUI6TNMF4NVRNJJRVI.jpg',
description: 'Tourists who comment on the lack of children in Washington have obviously never been to Capitol Hill/Hill East, where runners dodge strollers. There are several boutique hotels, bed-and-breakfasts and Airbnbs among the rowhouses occupied by lawmakers, lobbyists and lawyers.',
location: {
center: [-76.99011, 38.89004],
zoom: 16.00,
pitch: 60.00,
bearing: -27.17
},
onChapterEnter: [],
onChapterExit: []
},
{
id: 'Open City',
title: 'Open City',
image: 'https://www.washingtonpost.com/resizer/AtKWl5h37ZhpkyuIuGgtKLBUNXM=/1024x0/arc-anglerfish-washpost-prod-washpost.s3.amazonaws.com/public/ZGSWMFUDZUI6TNMF4NVRNJJRVI.jpg',
description: 'Originally located in Woodley Park, a neighborhood stuck in the 1960s in all the best ways, Open City is an upscale diner that puts a spin on American breakfast classics. Love hash browns? Order an entire bowl of them with two sunny-side-up eggs on top. If French toast is your thing, you can have it with hazelnuts. They have 18 breakfast entrees on the menu all day, every day. They also serve their own blend of Common Grounds coffee, made specially for their sister shop, Tryst.<br><b>BTW:</b><i> It’s about a half-mile from the National Zoo — a good place to walk off that fried chicken and waffle.</i>',
location: {
center: [-77.05222, 38.92326],
zoom: 13.32,
pitch: 59.50,
bearing: 0.00
},
onChapterEnter: [],
onChapterExit: []
},
{
id: 'Copycat',
title: 'copycat',
image: 'https://www.washingtonpost.com/resizer/vevFNXKWozKh0cE-As1biliJlQ4=/1024x0/arc-anglerfish-washpost-prod-washpost.s3.amazonaws.com/public/WULLXPUDZUI6TNMF4NVRNJJRVI.jpg',
description: 'This H Street NE spot pulls double duty. The bottom floor is a Chinese street-food shop, with bar and window seating only. The chef makes pot stickers, bao and skewers right in front of you. When you’re ready for a drink, head upstairs to the bar, where the city’s bartenders hang out. Because of that, order the “bartender’s choice” to give them the opportunity to show off their skills.<br> <b>BTW:</b><i>The “triple delight” pot stickers and cheeseburger bao are their bestsellers.</i>',
location: {
center: [-76.99105, 38.90034],
zoom: 18.64,
pitch: 59.50,
bearing: 0.00
},
onChapterEnter: [],
onChapterExit: []
}
]
};
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>By the Way a locals guide to Washington, DC</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.3.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.3.1/mapbox-gl.css' rel='stylesheet' />
<script src="https://unpkg.com/[email protected]/intersection-observer.js"></script>
<script src="https://unpkg.com/scrollama"></script>
<style>
body {
margin:0;
padding:0;
}
#map {
top:0;
height: 100vh;
width:100vw;
position: fixed;
z-index: -5;
}
#features {
padding-top: 30vh;
padding-bottom: 30vh;
font-family: sans-serif;
z-index: 100;
}
.centered {
width: 50vw;
margin: 0 auto;
}
.lefty {
width: 33vw;
margin-left: 5vw;
}
.righty {
width: 33vw;
margin-left: 62vw;
}
.step {
padding-bottom: 50vh;
/* margin-bottom: 10vh; */
opacity: 0.25;
}
.step.active {
opacity: 0.9;
}
.step div {
padding: 25px 50px;
line-height: 25px;
background-color: #fafafa;
border-bottom: 1px solid #ddd;
font-size: 13px;
}
.step img {
width: 100%;
}
@media (max-width: 750px) {
#features {
width: 90vw;
margin: 0 auto;
}
}
</style>
</head>
<body>
<div id='map'></div>
<div id='features'></div>
<script src="./config.js"></script>
<script>
var layerTypes = {
'fill': ['fill-opacity'],
'line': ['line-opacity'],
'circle': ['circle-opacity', 'circle-stroke-opacity'],
'symbol': ['icon-opacity', 'text-opacity'],
'raster': ['raster-opacity'],
'fill-extrusion': ['fill-extrusion-opacity']
}
var alignments = {
'left': 'lefty',
'center': 'centered',
'right': 'righty'
}
function getLayerPaintType(layer) {
var layerType = map.getLayer(layer).type;
return layerTypes[layerType];
}
function setLayerOpacity(layer) {
var paintProps = getLayerPaintType(layer.layer);
paintProps.forEach(function(prop) {
map.setPaintProperty(layer.layer, prop, layer.opacity);
});
}
var features = document.getElementById('features');
features.classList.add(alignments[config.alignment]);
config.chapters.forEach((record, idx) => {
var container = document.createElement('div');
var chapter = document.createElement('div');
if (record.title) {
var title = document.createElement('h3');
title.innerText = record.title;
chapter.appendChild(title);
}
if (record.image) {
var image = new Image();
image.src = record.image;
chapter.appendChild(image);
}
if (record.description) {
var story = document.createElement('p');
story.innerHTML = record.description;
chapter.appendChild(story);
}
container.setAttribute('id', record.id);
container.classList.add('step');
if (idx === 0) {
container.classList.add('active');
}
container.appendChild(chapter);
features.appendChild(container);
})
mapboxgl.accessToken = config.accessToken;
var map = new mapboxgl.Map({
container: 'map',
style: config.style,
center: config.mapStart.center,
zoom: config.mapStart.zoom,
bearing: config.mapStart.bearing,
pitch: config.mapStart.pitch,
scrollZoom: false
});
var marker = new mapboxgl.Marker();
if (config.showMarkers) {
marker.setLngLat(config.mapStart.center).addTo(map);
}
// instantiate the scrollama
var scroller = scrollama();
map.on("load", function() {
// setup the instance, pass callback functions
scroller
.setup({
step: '.step',
offset: 0.5,
progress: true
})
.onStepEnter(response => {
var chapter = config.chapters.find(chap => chap.id === response.element.id);
response.element.classList.add('active');
map.flyTo(chapter.location);
if (config.showMarkers) {
marker.setLngLat(chapter.location.center);
}
if (chapter.onChapterEnter.length > 0) {
chapter.onChapterEnter.forEach(setLayerOpacity);
}
})
.onStepExit(response => {
var chapter = config.chapters.find(chap => chap.id === response.element.id);
response.element.classList.remove('active');
if (chapter.onChapterExit.length > 0) {
chapter.onChapterExit.forEach(setLayerOpacity);
}
});
});
// setup resize event
window.addEventListener('resize', scroller.resize);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment