Skip to content

Commit

Permalink
Create storytelling.js
Browse files Browse the repository at this point in the history
  • Loading branch information
cameronkruse committed Mar 16, 2023
1 parent 50f986f commit c02d328
Showing 1 changed file with 390 additions and 0 deletions.
390 changes: 390 additions & 0 deletions hostedcontent/pk-flood/storytelling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,390 @@
var initLoad = true;
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"],
heatmap: ["heatmap-opacity"],
};
// custom
let floodDays = ["ff_230", "ff_234", "ff_239", "ff_242", "ff_246", "ff_249", "ff_251", "ff_253", "ff_254", "ff_258", "ff_261", "ff_263", "ff_265", "ff_266"];

function animateFlood(day) {
if (day == "flat") {
map.setPaintProperty("flood3d", "fill-extrusion-height", 0);
}
let fillString = ["+"];
for (let i = 0; i < day; i++) {
fillString.push(["get", floodDays[i]]);
}
console.log(fillString);
map.setPaintProperty("flood3d", "fill-extrusion-height", fillString);
}
// custom end
var alignments = {
left: "lefty",
center: "centered",
right: "righty",
full: "fully",
};

function getLayerPaintType(layer) {
var layerType = map.getLayer(layer).type;
return layerTypes[layerType];
}

function setLayerOpacity(layer) {
if (layer["fill-extrusion-height"]) {
console.log(layer["fill-extrusion-height"]);
animateFlood(layer["fill-extrusion-height"]);
} else {
var paintProps = getLayerPaintType(layer.layer);
// console.log(paintProps);
paintProps.forEach(function (prop) {
var options = {};
if (layer.duration) {
var transitionProp = prop + "-transition";
options = { duration: layer.duration };
map.setPaintProperty(layer.layer, transitionProp, options);
}
map.setPaintProperty(layer.layer, prop, layer.opacity, options);
});
}
}

var story = document.getElementById("story");
var features = document.createElement("div");
features.setAttribute("id", "features");

var header = document.createElement("div");

if (config.title) {
var titleText = document.createElement("h1");
titleText.innerText = config.title;
header.appendChild(titleText);
}

if (config.subtitle) {
var subtitleText = document.createElement("h2");
subtitleText.innerText = config.subtitle;
header.appendChild(subtitleText);
}

if (config.byline) {
var bylineText = document.createElement("p");
bylineText.innerText = config.byline;
header.appendChild(bylineText);
}

if (header.innerText.length > 0) {
header.classList.add(config.theme);
header.setAttribute("id", "header");
story.appendChild(header);
}

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");
}

chapter.classList.add(config.theme);
container.appendChild(chapter);
container.classList.add(alignments[record.alignment] || "centered");
if (record.hidden) {
container.classList.add("hidden");
}
features.appendChild(container);
});

story.appendChild(features);

var footer = document.createElement("div");

if (config.footer) {
var footerText = document.createElement("p");
footerText.innerHTML = config.footer;
footer.appendChild(footerText);
}

if (footer.innerText.length > 0) {
footer.classList.add(config.theme);
footer.setAttribute("id", "footer");
story.appendChild(footer);
}

mapboxgl.accessToken = config.accessToken;

const transformRequest = (url) => {
const hasQuery = url.indexOf("?") !== -1;
const suffix = hasQuery ? "&pluginName=scrollytellingV2" : "?pluginName=scrollytellingV2";
return {
url: url + suffix,
};
};

var map = new mapboxgl.Map({
container: "map",
style: config.style,
center: config.chapters[0].location.center,
zoom: config.chapters[0].location.zoom,
bearing: config.chapters[0].location.bearing,
pitch: config.chapters[0].location.pitch,
interactive: false,
transformRequest: transformRequest,
projection: config.projection,
});

// Create a inset map if enabled in config.js
if (config.inset) {
var insetMap = new mapboxgl.Map({
container: "mapInset", // container id
style: "mapbox://styles/mapbox/dark-v10", //hosted style id
center: config.chapters[0].location.center,
// Hardcode above center value if you want insetMap to be static.
zoom: 3, // starting zoom
hash: false,
interactive: false,
attributionControl: false,
//Future: Once official mapbox-gl-js has globe view enabled,
//insetmap can be a globe with the following parameter.
//projection: 'globe'
});
}

if (config.showMarkers) {
var marker = new mapboxgl.Marker({ color: config.markerColor });
marker.setLngLat(config.chapters[0].location.center).addTo(map);
}

// instantiate the scrollama
var scroller = scrollama();

map.on("load", function () {
if (config.use3dTerrain) {
map.addSource("mapbox-dem", {
type: "raster-dem",
url: "mapbox://mapbox.mapbox-terrain-dem-v1",
tileSize: 512,
maxzoom: 14,
});
// add the DEM source as a terrain layer with exaggerated height
map.setTerrain({ source: "mapbox-dem", exaggeration: 1.5 });

// add a sky layer that will show when the map is highly pitched
map.addLayer({
id: "sky",
type: "sky",
paint: {
"sky-type": "atmosphere",
"sky-atmosphere-sun": [0.0, 0.0],
"sky-atmosphere-sun-intensity": 15,
},
});
}
// ADD Custom layers
map.addSource("flood", {
type: "vector",
url: "mapbox://highestroad.blex374p",
});
map.addLayer({
id: "flood3d",
type: "fill-extrusion",
source: "flood",
"source-layer": "firstflood-grid-cleaned-c04q87",
paint: {
"fill-extrusion-opacity": 0,
"fill-extrusion-color": ["interpolate", ["linear"], ["get", "flood_sum"], 10323, "#d8e4ee", 64140, "#11304b"],
"fill-extrusion-height": 0,
},
}, "agflood0-grid");

// As the map moves, grab and update bounds in inset map.
if (config.inset) {
map.on("move", getInsetBounds);
}
// setup the instance, pass callback functions
scroller
.setup({
step: ".step",
offset: 0.5,
progress: true,
})
.onStepEnter(async (response) => {
var current_chapter = config.chapters.findIndex((chap) => chap.id === response.element.id);
var chapter = config.chapters[current_chapter];
if (chapter.fullPhoto) {
document.getElementById("full-photo").style["background-image"] = "url(" + chapter.fullPhoto + ")";
// document.getElementById("photo").style["background-position"] = chapter.photoposition;
document.getElementById("full-photo").style.opacity = "100";
document.getElementById("map").style.opacity = "0";
} else {
document.getElementById("full-photo").style.opacity = "0";
document.getElementById("map").style.opacity = "100";
}
if (chapter.map3d) {
// make map 3d
map.setTerrain({ source: "mapbox-dem", exaggeration: 1.5 });
} else {
map.setTerrain();
}
if (chapter.date) {
// const stepDivs =
document.querySelectorAll('.step div').forEach(div => {
div.style.backgroundColor = '#eee9e000';
div.style.webkitBoxShadow = '5px 5px 10px 0px rgba(0, 0, 0, 0.0)';
});

} else {
document.querySelectorAll('.step div').forEach(div => {
div.style.backgroundColor = '#eee9e0';
div.style.webkitBoxShadow = '5px 5px 10px 0px rgba(0, 0, 0, 0.5)';
});
}

response.element.classList.add("active");
map[chapter.mapAnimation || "flyTo"](chapter.location);

// Incase you do not want to have a dynamic inset map,
// rather want to keep it a static view but still change the
// bbox as main map move: comment out the below if section.
if (config.inset) {
if (chapter.location.zoom < 5) {
insetMap.flyTo({ center: chapter.location.center, zoom: 0 });
} else {
insetMap.flyTo({ center: chapter.location.center, zoom: 3 });
}
}
if (config.showMarkers) {
marker.setLngLat(chapter.location.center);
}
if (chapter.onChapterEnter.length > 0) {
chapter.onChapterEnter.forEach(setLayerOpacity);
}
if (chapter.callback) {
window[chapter.callback]();
}
if (chapter.rotateAnimation) {
map.once("moveend", () => {
const rotateNumber = map.getBearing();
map.rotateTo(rotateNumber + 180, {
duration: 30000,
easing: function (t) {
return t;
},
});
});
}
if (config.auto) {
var next_chapter = (current_chapter + 1) % config.chapters.length;
map.once("moveend", () => {
document.querySelectorAll('[data-scrollama-index="' + next_chapter.toString() + '"]')[0].scrollIntoView();
});
}
})
.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);
}
});

if (config.auto) {
document.querySelectorAll('[data-scrollama-index="0"]')[0].scrollIntoView();
}
});

//Helper functions for insetmap
function getInsetBounds() {
let bounds = map.getBounds();

let boundsJson = {
type: "FeatureCollection",
features: [
{
type: "Feature",
properties: {},
geometry: {
type: "Polygon",
coordinates: [
[
[bounds._sw.lng, bounds._sw.lat],
[bounds._ne.lng, bounds._sw.lat],
[bounds._ne.lng, bounds._ne.lat],
[bounds._sw.lng, bounds._ne.lat],
[bounds._sw.lng, bounds._sw.lat],
],
],
},
},
],
};

if (initLoad) {
addInsetLayer(boundsJson);
initLoad = false;
} else {
updateInsetLayer(boundsJson);
}
}

function addInsetLayer(bounds) {
insetMap.addSource("boundsSource", {
type: "geojson",
data: bounds,
});

insetMap.addLayer({
id: "boundsLayer",
type: "fill",
source: "boundsSource", // reference the data source
layout: {},
paint: {
"fill-color": "#fff", // blue color fill
"fill-opacity": 0.2,
},
});
// // Add a black outline around the polygon.
insetMap.addLayer({
id: "outlineLayer",
type: "line",
source: "boundsSource",
layout: {},
paint: {
"line-color": "#000",
"line-width": 1,
},
});
}

function updateInsetLayer(bounds) {
insetMap.getSource("boundsSource").setData(bounds);
}

// setup resize event
window.addEventListener("resize", scroller.resize);

0 comments on commit c02d328

Please sign in to comment.