Skip to content

Instantly share code, notes, and snippets.

@ejfox
Created September 13, 2022 14:46
Show Gist options
  • Save ejfox/7b6a12465e0dea8e4eea1fb8a6af840a to your computer and use it in GitHub Desktop.
Save ejfox/7b6a12465e0dea8e4eea1fb8a6af840a to your computer and use it in GitHub Desktop.
<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