Created
September 13, 2022 14:46
-
-
Save ejfox/7b6a12465e0dea8e4eea1fb8a6af840a to your computer and use it in GitHub Desktop.
This file contains hidden or 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
<template> | |
<section class="hero-map-container ba b--white bw2 bw3-l" ref="root"> | |
<div id="map" class="w-100 vh-100 z-1 top-0" ref="mapRoot"></div> | |
<div ref="mapText" class="map-text relative z-999 ml5-l measure"> | |
<p data-lat="35.102215" data-lng="-89.999185">TK 1</p> | |
<p | |
data-lat="35.12587" | |
data-lng="-90.0362" | |
data-place-marker="true" | |
data-marker-color="blue" | |
data-marker-text="Frank Sr. former home" | |
> | |
TK 2 | |
</p> | |
</div> | |
</section> | |
</template> | |
<script> | |
// import * as d3 from 'd3' | |
// import turf | |
import { | |
centerOfMass, | |
point, | |
featureCollection, | |
feature, | |
bbox, | |
} from '@turf/turf' | |
import * as mapboxgl from 'mapbox-gl' | |
import 'mapbox-gl/dist/mapbox-gl.css' | |
// import scrollama from 'scrollama' | |
export default { | |
props: {}, | |
data: function () { | |
return { | |
map: null, | |
focusedEl: null, | |
containerScrollY: 0, | |
focused: false, | |
initialZoom: 5, | |
focusedZoom: 16, | |
zoomDuration: 3300, | |
} | |
}, | |
computed: { | |
isMobile: function () { | |
const screenWidth = window.innerWidth | |
return screenWidth < 768 | |
}, | |
}, | |
mounted: function () { | |
this.setUpMapboxMap() | |
// const scroller = scrollama() | |
// scroller | |
// .setup({ | |
// step: '.map-text p', | |
// // debug: true, | |
// // offset: 0.75, | |
// offset: 0.92, | |
// }) | |
// .onStepEnter(this.onStepEnter) | |
// set up scroll listener | |
window.addEventListener('scroll', this.onScroll) | |
}, | |
watch: { | |
focused: function (newVal, oldVal) { | |
if (newVal) { | |
this.onMapFocused() | |
} else if (oldVal && !newVal) { | |
this.onMapUnfocused() | |
} | |
}, | |
}, | |
methods: { | |
onStepEnter(step) { | |
const el = step.element | |
// console.log('step', step, el) | |
this.focusedEl = el | |
const zoomDuration = this.zoomDuration | |
const lat = el.getAttribute('data-lat') | |
const lng = el.getAttribute('data-lng') | |
const placeMarker = el.getAttribute('data-place-marker') | |
const markerColor = el.getAttribute('data-marker-color') | |
const markerText = el.getAttribute('data-marker-text') | |
if (!lng || !lat) return | |
this.map.flyTo({ | |
center: [lng, lat], | |
zoom: this.focusedZoom, | |
duration: this.zoomDuration, | |
}) | |
}, | |
flyToLocation(location) { | |
this.map.flyTo({ | |
center: [location.lng, location.lat], | |
zoom: this.focusedZoom * 1.3, | |
duration: this.zoomDuration, | |
}) | |
}, | |
onMapUnfocused: function () { | |
// this.map.fitBounds(bbox(focusAreaGeojson), { | |
// duration: this.zoomDuration * 1.4, | |
// padding: { | |
// left: 0, | |
// right: 0, | |
// top: 0, | |
// bottom: 0, | |
// }, | |
// }) | |
}, | |
onMapFocused: function () { | |
// const zoomDuration = 8000 | |
// fit to bounds of whole Memphis | |
// this.map.fitBounds(bbox(wholeAreaGeoJson), { | |
// duration: zoomDuration, | |
// padding: { | |
// left: 20, | |
// right: 20, | |
// top: 20, | |
// bottom: 20, | |
// }, | |
// }) | |
// this.map.easeTo({ | |
// zoom: this.focusedZoom, | |
// pitch: 55, | |
// bearing: -32, | |
// duration: zoomDuration, | |
// }) | |
}, | |
setUpMapboxMap: function () { | |
this.map = new mapboxgl.Map({ | |
container: this.$refs.mapRoot, | |
// style: 'mapbox://styles/mapbox/streets-v11', | |
// satellite style | |
// style: 'mapbox://styles/mapbox/satellite-v9', | |
style: 'mapbox://styles/ejfox/cl7p0rxav000o15p0dnsl8jen', | |
accessToken: | |
'pk.eyJ1IjoiZWpmb3giLCJhIjoiY2lyZjd0bXltMDA4b2dma3JzNnA0ajh1bSJ9.iCmlE7gmJubz2RtL4RFzIw', | |
center: [-89.99542, 35.08652], | |
zoom: this.initialZoom, | |
// 'pk.eyJ1IjoiZWpmb3giLCJhIjoiY2lyZjd0bXltMDA4b2dma3JzNnA0ajh1bSJ9.iCmlE7gmJubz2RtL4RFzIw', | |
// projection: 'globe', | |
projection: 'mercator', | |
}) | |
this.map.on('load', this.onMapLoaded) | |
// Disable zoom scrolling | |
this.map.scrollZoom.disable() | |
// Disable panning | |
if (this.isMobile) this.map.dragPan.disable() | |
}, | |
onMapLoaded: function () { | |
// add mapboxgl controls | |
this.map.addControl(new mapboxgl.NavigationControl()) | |
this.map.easeTo({ | |
pitch: 45, | |
duration: 0, | |
}) | |
// add memphis depot as geojson, with orange fill | |
// this.map.addSource('highlight', { | |
// type: 'geojson', | |
// data: highlightGeojson, | |
// }) | |
// this.map.addLayer({ | |
// id: 'highlight-fill', | |
// type: 'fill', | |
// source: 'highlight', | |
// paint: { | |
// 'fill-color': '#ff7f00', | |
// 'fill-opacity': 0.2, | |
// }, | |
// }) | |
}, | |
onScroll: function (e) { | |
this.containerScrollY = this.calcContainerScrollY(e) | |
if (!this.$refs.root) return | |
const containerHeight = this.$refs.root.offsetHeight | |
// if containerScrollY is negative, not in focus for the height of the element | |
if (this.containerScrollY < 0) { | |
this.focused = false | |
} else if (this.containerScrollY > containerHeight) { | |
this.focused = false | |
} else { | |
this.focused = true | |
} | |
}, | |
calcContainerScrollY: function (e) { | |
const containerEl = this.$refs.root | |
if (!containerEl) return false | |
/* figure out how many pixels have been scrolled in container */ | |
let containerScrollY = containerEl.getBoundingClientRect().top | |
// invert the number from negative to positive | |
containerScrollY = -containerScrollY | |
return containerScrollY | |
}, | |
}, | |
} | |
</script> | |
<style scoped> | |
#map { | |
position: sticky; | |
} | |
.vh-80 { | |
height: 80vh; | |
} | |
.hero-map-container { | |
/* position: sticky; | |
top: 1rem; */ | |
} | |
p { | |
margin-bottom: 48vh; | |
padding: 2em 1.2em; | |
margin-left: 2vw; | |
margin-right: 2vw; | |
line-height: 1.3em; | |
background-color: white; | |
border-radius: 0.25rem; | |
box-shadow: 0 0 3.3rem rgba(0, 0, 0, 0.15); | |
border: 1px solid white; | |
} | |
.sticky { | |
position: sticky; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment