Skip to content

Instantly share code, notes, and snippets.

@mojodna
Last active October 3, 2018 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mojodna/49e42f58ab1ea6d560de584c1d1d3edf to your computer and use it in GitHub Desktop.
Save mojodna/49e42f58ab1ea6d560de584c1d1d3edf to your computer and use it in GitHub Desktop.
Mapping of Detroit by month
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.45.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.45.0/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
button {
position: absolute;
margin: 20px;
right: 0;
bottom: 0;
}
p#timecode {
position: absolute;
bottom: 0px;
left: 20px;
font-family: "DIN Alternate";
color: white;
font-size: 32px;
}
#pause::after {
content: 'Pause';
}
#pause.pause::after {
content: 'Play';
}
</style>
</head>
<body>
<div id='map'></div>
<button id='pause' class="pause"></button>
<p id="timecode"></p>
<script>
var now = Date.now();
var simple = {
version: 8,
sources: {
"all": {
type: "vector",
tiles: [
"https://osm-detroit.s3.amazonaws.com/detroit-geom-tiles-20180930/{z}/{x}/{y}.mvt"
]
}
},
layers: [
{
id: "background",
type: "background",
paint: {
"background-color": "#09599d"
}
},
{
id: "active-lines",
type: "line",
source: "all",
"source-layer": "all",
minzoom: 14,
maxzoom: 24,
paint: {
"line-color": "#ccc",
"line-opacity": 0.05,
"line-width": 2.5,
"line-blur": 5
},
layout: {
"line-cap": "butt",
"line-join": "round",
visibility: "none"
}
},
{
id: "active-points",
type: "circle",
source: "all",
"source-layer": "all",
minzoom: 14,
maxzoom: 24,
paint: {
"circle-radius": 2.5,
"circle-color": "#ccc",
"circle-opacity": 0.05,
"circle-blur": 5
},
layout: {
visibility: "none"
}
},
{
id: "active-polygons",
type: "fill",
source: "all",
"source-layer": "all",
minzoom: 14,
maxzoom: 24,
paint: {
"fill-color": "#ccc",
"fill-opacity": 0.01
},
layout: {
visibility: "none"
}
},
{
id: "lines",
type: "line",
source: "all",
"source-layer": "all",
minzoom: 14,
maxzoom: 24,
paint: {
"line-color": "#fff",
"line-opacity": 0.1
},
layout: {
"line-cap": "butt",
"line-join": "round",
visibility: "none"
}
},
{
id: "points",
type: "circle",
source: "all",
"source-layer": "all",
minzoom: 14,
maxzoom: 24,
paint: {
"circle-radius": 2,
"circle-color": "#fff",
"circle-opacity": 0.1,
"circle-blur": 1
},
layout: {
visibility: "none"
}
},
{
id: "polygons",
type: "fill",
source: "all",
"source-layer": "all",
minzoom: 14,
maxzoom: 24,
paint: {
"fill-color": "#fff",
"fill-opacity": 0.01
},
layout: {
visibility: "none"
}
}
]
};
mapboxgl.accessToken =
"pk.eyJ1IjoibW9qb2RuYSIsImEiOiJMRy1RU0NrIn0.wNBlZL1Hmx2TxsKMeE1xwg";
var map = new mapboxgl.Map({
container: "map",
style: simple,
center: [-83.0611, 42.3395],
zoom: 15.00,
hash: true
});
var animation; // to store and cancel the animation
var startTime = 0;
var progress = 0; // progress = timestamp - startTime
var resetTime = false; // indicator of whether time reset is needed for the animation
var pauseButton = document.getElementById("pause");
var startDate = new Date("2007-09-01T00:00:00Z");
// var startDate = new Date("2010-05-01T00:00:00Z");
// var startDate = new Date("2012-01-01T00:00:00Z");
var currentDate = startDate.getTime();
var pointFilter = [["==", "$type", "Point"]];
var lineFilter = [["==", "$type", "LineString"]];
var polygonFilter = [["==", "$type", "Polygon"]];
map.on("load", function() {
startTime = performance.now();
map.setLayoutProperty("points", "visibility", "visible")
map.setLayoutProperty("lines", "visibility", "visible");
map.setLayoutProperty("polygons", "visibility", "visible");
map.setFilter("points", ["all", ["==", "__validUntil", 0]].concat(pointFilter));
map.setFilter("lines", ["all", ["==", "__validUntil", 0]].concat(lineFilter));
map.setFilter("polygons", ["all", ["==", "__validUntil", 0]].concat(polygonFilter));
// animate();
var cancelled = false;
// click the button to pause or play
pauseButton.addEventListener("click", function() {
pauseButton.classList.toggle("pause");
if (pauseButton.classList.contains("pause")) {
// cancelAnimationFrame(animation);
cancelled = true;
} else {
resetTime = true;
animate();
}
});
// reset startTime and progress once the tab loses or gains focus
// requestAnimationFrame also pauses on hidden tabs by default
document.addEventListener("visibilitychange", function() {
resetTime = true;
});
function animate() {
var d = startDate.getTime();
var filters = [
"all",
["<=", "updated", d],
[
"any",
["all", [">", "__validUntil", d], ["!=", "__validUntil", 0]],
["==", "__validUntil", 0]
]
];
map.setFilter("points", filters.concat(pointFilter));
map.setFilter("lines", filters.concat(lineFilter));
map.setFilter("polygons", filters.concat(polygonFilter));
map.setFilter("active-points", ["all", [">=", "__updated", now]].concat(pointFilter));
map.setFilter("active-lines", ["all", [">=", "__updated", now]].concat(lineFilter));
map.setFilter("active-polygons", ["all", [">=", "__updated", now]].concat(polygonFilter));
map.setLayoutProperty("points", "visibility", "visible")
map.setLayoutProperty("lines", "visibility", "visible");
map.setLayoutProperty("polygons", "visibility", "visible");
map.setLayoutProperty("active-points", "visibility", "visible");
map.setLayoutProperty("active-lines", "visibility", "visible");
map.setLayoutProperty("active-polygons", "visibility", "visible");
animateFrame();
}
// updated >= show
// show < validUntil
// var interval = 86400e3;
// var interval = 604800e3;
var interval = 86400e3 * 365 / 12;
var dateFormatter = new Intl.DateTimeFormat("en-US");
function animateFrame() {
currentDate += interval;
var show = currentDate;
document.getElementById("timecode").textContent = dateFormatter.format(new Date(currentDate));
// console.log(show);
var filters = [
"all",
["<=", "__updated", show],
[
"any",
["all", [">", "__validUntil", show], ["!=", "__validUntil", 0]],
["==", "__validUntil", 0]
]
];
map.setFilter("lines", filters.concat(lineFilter));
map.setFilter("points", filters.concat(pointFilter));
map.setFilter("polygons", filters.concat(polygonFilter));
var activeFilter = [
"all",
[">=", "__updated", new Date(currentDate - 1 * interval).getTime()],
["<", "__updated", new Date(currentDate + 7 * interval).getTime()]
];
map.setFilter("active-lines", activeFilter.concat(lineFilter));
map.setFilter("active-points", activeFilter.concat(pointFilter));
map.setFilter("active-polygons", activeFilter.concat(polygonFilter));
if (currentDate + interval > Date.now()) {
// currentDate = startDate.getTime();
cancelled = true;
}
if (!cancelled) {
setTimeout(() => animateFrame(), 500);
}
// map.once("render", animateFrame)
// Request the next frame of the animation.
// animation = requestAnimationFrame(animateFrame);
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment