New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

scrollama

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scrollama - npm Package Compare versions

Comparing version 1.4.4 to 2.0.0

docs/sticky-overlay/index.html

590

build/scrollama.js

@@ -19,10 +19,2 @@ (function (global, factory) {

// public
function select(selector) {
if (selector instanceof Element) { return selector; }
else if (typeof selector === 'string')
{ return document.querySelector(selector); }
return null;
}
function selectAll(selector, parent) {

@@ -129,39 +121,47 @@ if ( parent === void 0 ) parent = document;

function scrollama() {
var ZERO_MOE = 1; // zero with some rounding margin of error
var callback = {};
var OBSERVER_NAMES = [
'stepAbove',
'stepBelow',
'stepProgress',
'viewportAbove',
'viewportBelow'
];
var cb = {
stepEnter: function () {},
stepExit: function () {},
stepProgress: function () {}
};
var io = {};
var containerEl = null;
var graphicEl = null;
var stepEl = null;
var id = null;
var stepEl = [];
var stepOffsetHeight = [];
var stepOffsetTop = [];
var stepStates = [];
var id = null;
var offsetVal = 0;
var offsetMargin = 0;
var vh = 0;
var ph = 0;
var stepOffsetHeight = null;
var stepOffsetTop = null;
var bboxGraphic = null;
var viewH = 0;
var pageH = 0;
var previousYOffset = 0;
var progressThreshold = 0;
var isReady = false;
var isEnabled = false;
var debugMode = false;
var isDebug = false;
var progressMode = false;
var progressThreshold = 0;
var preserveOrder = false;
var triggerOnce = false;
var stepStates = null;
var containerState = null;
var previousYOffset = -1;
var direction = null;
var direction = 'down';
var exclude = [];
// HELPERS
function generateId() {
/*** HELPERS ***/
function generateInstanceID() {
var a = 'abcdefghijklmnopqrstuv';
var l = a.length;
var t = new Date().getTime();
var t = Date.now();
var r = [0, 0, 0].map(function (d) { return a[Math.floor(Math.random() * l)]; }).join('');

@@ -211,18 +211,19 @@ return ("" + r + t);

function disconnectObserver(name) {
if (io[name]) { io[name].forEach(function (d) { return d.disconnect(); }); }
}
function handleResize() {
vh = window.innerHeight;
ph = getPageHeight();
viewH = window.innerHeight;
pageH = getPageHeight();
bboxGraphic = graphicEl ? graphicEl.getBoundingClientRect() : null;
offsetMargin = offsetVal * viewH;
offsetMargin = offsetVal * vh;
if (isReady) {
stepOffsetHeight = stepEl.map(function (el) { return el.offsetHeight; });
stepOffsetTop = stepEl.map(getOffsetTop);
if (isEnabled) { updateIO(); }
}
stepOffsetHeight = stepEl ? stepEl.map(function (el) { return el.offsetHeight; }) : [];
stepOffsetTop = stepEl ? stepEl.map(getOffsetTop) : [];
if (isEnabled && isReady) { updateIO(); }
if (debugMode)
{ update({ id: id, stepOffsetHeight: stepOffsetHeight, offsetMargin: offsetMargin, offsetVal: offsetVal }); }
if (isDebug) { update({ id: id, stepOffsetHeight: stepOffsetHeight, offsetMargin: offsetMargin, offsetVal: offsetVal }); }
}

@@ -234,12 +235,6 @@

isEnabled = true;
} else if (!enable) {
if (io.top) { io.top.disconnect(); }
if (io.bottom) { io.bottom.disconnect(); }
if (io.stepAbove) { io.stepAbove.forEach(function (d) { return d.disconnect(); }); }
if (io.stepBelow) { io.stepBelow.forEach(function (d) { return d.disconnect(); }); }
if (io.stepProgress) { io.stepProgress.forEach(function (d) { return d.disconnect(); }); }
if (io.viewportAbove) { io.viewportAbove.forEach(function (d) { return d.disconnect(); }); }
if (io.viewportBelow) { io.viewportBelow.forEach(function (d) { return d.disconnect(); }); }
isEnabled = false;
return true;
}
OBSERVER_NAMES.forEach(disconnectObserver);
isEnabled = false;
}

@@ -257,3 +252,12 @@

// NOTIFY CALLBACKS
/*** NOTIFY CALLBACKS ***/
function notifyStepProgress(element, progress) {
var index = getIndex(element);
if (progress !== undefined) { stepStates[index].progress = progress; }
var resp = { element: element, index: index, progress: stepStates[index].progress };
if (stepStates[index].state === 'enter') { cb.stepProgress(resp); }
}
function notifyOthers(index, location) {

@@ -264,7 +268,10 @@ if (location === 'above') {

var ss = stepStates[i];
if (ss.state === 'enter') { notifyStepExit(stepEl[i], 'down'); }
if (ss.direction === 'up') {
if (ss.state !== 'enter' && ss.direction !== 'down') {
notifyStepEnter(stepEl[i], 'down', false);
notifyStepExit(stepEl[i], 'down');
}
} else if (ss.state === 'enter') { notifyStepExit(stepEl[i], 'down'); }
// else if (ss.direction === 'up') {
// notifyStepEnter(stepEl[i], 'down', false);
// notifyStepExit(stepEl[i], 'down');
// }
}

@@ -294,3 +301,2 @@ } else if (location === 'below') {

stepStates[index].state = 'enter';
if (preserveOrder && check && direction === 'down')

@@ -302,16 +308,9 @@ { notifyOthers(index, 'above'); }

if (
callback.stepEnter &&
typeof callback.stepEnter === 'function' &&
!exclude[index]
) {
callback.stepEnter(resp, stepStates);
if (debugMode) { notifyStep({ id: id, index: index, state: 'enter' }); }
if (cb.stepEnter && !exclude[index]) {
cb.stepEnter(resp, stepStates);
if (isDebug) { notifyStep({ id: id, index: index, state: 'enter' }); }
if (triggerOnce) { exclude[index] = true; }
}
if (progressMode) {
if (direction === 'down') { notifyStepProgress(element, 0); }
else { notifyStepProgress(element, 1); }
}
if (progressMode) { notifyStepProgress(element); }
}

@@ -323,2 +322,9 @@

if (progressMode) {
if (direction === 'down' && stepStates[index].progress < 1)
{ notifyStepProgress(element, 1); }
else if (direction === 'up' && stepStates[index].progress > 0)
{ notifyStepProgress(element, 0); }
}
// store most recent trigger

@@ -328,104 +334,83 @@ stepStates[index].direction = direction;

if (progressMode) {
if (direction === 'down') { notifyStepProgress(element, 1); }
else { notifyStepProgress(element, 0); }
}
if (callback.stepExit && typeof callback.stepExit === 'function') {
callback.stepExit(resp, stepStates);
if (debugMode) { notifyStep({ id: id, index: index, state: 'exit' }); }
}
cb.stepExit(resp, stepStates);
if (isDebug) { notifyStep({ id: id, index: index, state: 'exit' }); }
}
function notifyStepProgress(element, progress) {
var index = getIndex(element);
var resp = { element: element, index: index, progress: progress };
if (callback.stepProgress && typeof callback.stepProgress === 'function')
{ callback.stepProgress(resp); }
}
/*** OBSERVER - INTERSECT HANDLING ***/
// this is good for entering while scrolling down + leaving while scrolling up
function intersectStepAbove(ref) {
var entry = ref[0];
function notifyContainerEnter() {
var resp = { direction: direction };
containerState.direction = direction;
containerState.state = 'enter';
updateDirection();
var isIntersecting = entry.isIntersecting;
var boundingClientRect = entry.boundingClientRect;
var target = entry.target;
// bottom = bottom edge of element from top of viewport
// bottomAdjusted = bottom edge of element from trigger
var top = boundingClientRect.top;
var bottom = boundingClientRect.bottom;
var topAdjusted = top - offsetMargin;
var bottomAdjusted = bottom - offsetMargin;
var index = getIndex(target);
var ss = stepStates[index];
// entering above is only when topAdjusted is negative
// and bottomAdjusted is positive
if (
callback.containerEnter &&
typeof callback.containerEnter === 'function'
isIntersecting &&
topAdjusted <= 0 &&
bottomAdjusted >= 0 &&
direction === 'down' &&
ss.state !== 'enter'
)
{ callback.containerEnter(resp); }
}
{ notifyStepEnter(target, direction); }
function notifyContainerExit() {
var resp = { direction: direction };
containerState.direction = direction;
containerState.state = 'exit';
if (callback.containerExit && typeof callback.containerExit === 'function')
{ callback.containerExit(resp); }
// exiting from above is when topAdjusted is positive and not intersecting
if (
!isIntersecting &&
topAdjusted > 0 &&
direction === 'up' &&
ss.state === 'enter'
)
{ notifyStepExit(target, direction); }
}
// OBSERVER - INTERSECT HANDLING
// this is good for entering while scrolling up + leaving while scrolling down
function intersectStepBelow(ref) {
var entry = ref[0];
// if TOP edge of step crosses threshold,
// bottom must be > 0 which means it is on "screen" (shifted by offset)
function intersectStepAbove(entries) {
updateDirection();
entries.forEach(function (entry) {
var isIntersecting = entry.isIntersecting;
var boundingClientRect = entry.boundingClientRect;
var target = entry.target;
var isIntersecting = entry.isIntersecting;
var boundingClientRect = entry.boundingClientRect;
var target = entry.target;
// bottom is how far bottom edge of el is from top of viewport
var bottom = boundingClientRect.bottom;
var height = boundingClientRect.height;
var bottomAdjusted = bottom - offsetMargin;
var index = getIndex(target);
var ss = stepStates[index];
// bottom = bottom edge of element from top of viewport
// bottomAdjusted = bottom edge of element from trigger
var top = boundingClientRect.top;
var bottom = boundingClientRect.bottom;
var topAdjusted = top - offsetMargin;
var bottomAdjusted = bottom - offsetMargin;
var index = getIndex(target);
var ss = stepStates[index];
if (bottomAdjusted >= -ZERO_MOE) {
if (isIntersecting && direction === 'down' && ss.state !== 'enter')
{ notifyStepEnter(target, direction); }
else if (!isIntersecting && direction === 'up' && ss.state === 'enter')
{ notifyStepExit(target, direction); }
else if (
!isIntersecting &&
bottomAdjusted >= height &&
direction === 'down' &&
ss.state === 'enter'
) {
notifyStepExit(target, direction);
}
}
});
}
// entering below is only when bottomAdjusted is positive
// and topAdjusted is positive
if (
isIntersecting &&
topAdjusted <= 0 &&
bottomAdjusted >= 0 &&
direction === 'up' &&
ss.state !== 'enter'
)
{ notifyStepEnter(target, direction); }
function intersectStepBelow(entries) {
updateDirection();
entries.forEach(function (entry) {
var isIntersecting = entry.isIntersecting;
var boundingClientRect = entry.boundingClientRect;
var target = entry.target;
var bottom = boundingClientRect.bottom;
var height = boundingClientRect.height;
var bottomAdjusted = bottom - offsetMargin;
var index = getIndex(target);
var ss = stepStates[index];
if (
bottomAdjusted >= -ZERO_MOE &&
bottomAdjusted < height &&
isIntersecting &&
direction === 'up' &&
ss.state !== 'enter'
) {
notifyStepEnter(target, direction);
} else if (
bottomAdjusted <= ZERO_MOE &&
!isIntersecting &&
direction === 'down' &&
ss.state === 'enter'
) {
notifyStepExit(target, direction);
}
});
// exiting from above is when bottomAdjusted is negative and not intersecting
if (
!isIntersecting &&
bottomAdjusted < 0 &&
direction === 'down' &&
ss.state === 'enter'
)
{ notifyStepExit(target, direction); }
}

@@ -438,129 +423,66 @@

*/
function intersectViewportAbove(entries) {
function intersectViewportAbove(ref) {
var entry = ref[0];
updateDirection();
entries.forEach(function (entry) {
var isIntersecting = entry.isIntersecting;
var target = entry.target;
var index = getIndex(target);
var ss = stepStates[index];
if (
isIntersecting &&
direction === 'down' &&
ss.state !== 'enter' &&
ss.direction !== 'down'
) {
notifyStepEnter(target, 'down');
notifyStepExit(target, 'down');
}
});
}
var isIntersecting = entry.isIntersecting;
var target = entry.target;
var index = getIndex(target);
var ss = stepStates[index];
function intersectViewportBelow(entries) {
updateDirection();
entries.forEach(function (entry) {
var isIntersecting = entry.isIntersecting;
var target = entry.target;
var index = getIndex(target);
var ss = stepStates[index];
if (
isIntersecting &&
direction === 'up' &&
ss.state !== 'enter' &&
ss.direction !== 'up'
) {
notifyStepEnter(target, 'up');
notifyStepExit(target, 'up');
}
});
if (
isIntersecting &&
direction === 'down' &&
ss.direction !== 'down' &&
ss.state !== 'enter'
) {
notifyStepEnter(target, 'down');
notifyStepExit(target, 'down');
}
}
function intersectStepProgress(entries) {
updateDirection();
entries.forEach(
function (ref) {
var isIntersecting = ref.isIntersecting;
var intersectionRatio = ref.intersectionRatio;
var boundingClientRect = ref.boundingClientRect;
var target = ref.target;
function intersectViewportBelow(ref) {
var entry = ref[0];
var bottom = boundingClientRect.bottom;
var bottomAdjusted = bottom - offsetMargin;
if (isIntersecting && bottomAdjusted >= -ZERO_MOE) {
notifyStepProgress(target, +intersectionRatio.toFixed(3));
}
}
);
}
function intersectTop(entries) {
updateDirection();
var ref = entries[0];
var isIntersecting = ref.isIntersecting;
var boundingClientRect = ref.boundingClientRect;
var top = boundingClientRect.top;
var bottom = boundingClientRect.bottom;
if (bottom > -ZERO_MOE) {
if (isIntersecting) { notifyContainerEnter(direction); }
else if (containerState.state === 'enter') { notifyContainerExit(direction); }
var isIntersecting = entry.isIntersecting;
var target = entry.target;
var index = getIndex(target);
var ss = stepStates[index];
if (
isIntersecting &&
direction === 'up' &&
ss.direction === 'down' &&
ss.state !== 'enter'
) {
notifyStepEnter(target, 'up');
notifyStepExit(target, 'up');
}
}
function intersectBottom(entries) {
function intersectStepProgress(ref) {
var entry = ref[0];
updateDirection();
var ref = entries[0];
var isIntersecting = ref.isIntersecting;
var boundingClientRect = ref.boundingClientRect;
var top = boundingClientRect.top;
if (top < ZERO_MOE) {
if (isIntersecting) { notifyContainerEnter(direction); }
else if (containerState.state === 'enter') { notifyContainerExit(direction); }
var isIntersecting = entry.isIntersecting;
var intersectionRatio = entry.intersectionRatio;
var boundingClientRect = entry.boundingClientRect;
var target = entry.target;
var bottom = boundingClientRect.bottom;
var bottomAdjusted = bottom - offsetMargin;
if (isIntersecting && bottomAdjusted >= 0) {
notifyStepProgress(target, +intersectionRatio.toFixed(3));
}
}
// OBSERVER - CREATION
function updateTopIO() {
if (io.top) { io.top.unobserve(containerEl); }
var options = {
root: null,
rootMargin: (vh + "px 0px -" + vh + "px 0px"),
threshold: 0
};
io.top = new IntersectionObserver(intersectTop, options);
io.top.observe(containerEl);
}
function updateBottomIO() {
if (io.bottom) { io.bottom.unobserve(containerEl); }
var options = {
root: null,
rootMargin: ("-" + (bboxGraphic.height) + "px 0px " + (bboxGraphic.height) + "px 0px"),
threshold: 0
};
io.bottom = new IntersectionObserver(intersectBottom, options);
io.bottom.observe(containerEl);
}
// top edge
function updateStepAboveIO() {
if (io.stepAbove) { io.stepAbove.forEach(function (d) { return d.disconnect(); }); }
io.stepAbove = stepEl.map(function (el, i) {
var marginTop = stepOffsetHeight[i];
var marginBottom = -vh + offsetMargin;
/*** OBSERVER - CREATION ***/
// jump into viewport
function updateViewportAboveIO() {
io.viewportAbove = stepEl.map(function (el, i) {
var marginTop = pageH - stepOffsetTop[i];
var marginBottom = offsetMargin - viewH - stepOffsetHeight[i];
var rootMargin = marginTop + "px 0px " + marginBottom + "px 0px";
var options = {
root: null,
rootMargin: rootMargin,
threshold: 0
};
var obs = new IntersectionObserver(intersectStepAbove, options);
var options = { rootMargin: rootMargin };
// console.log(options);
var obs = new IntersectionObserver(intersectViewportAbove, options);
obs.observe(el);

@@ -571,18 +493,10 @@ return obs;

// bottom edge
function updateStepBelowIO() {
if (io.stepBelow) { io.stepBelow.forEach(function (d) { return d.disconnect(); }); }
io.stepBelow = stepEl.map(function (el, i) {
var marginTop = -offsetMargin;
var marginBottom = ph - vh + stepOffsetHeight[i] + offsetMargin;
function updateViewportBelowIO() {
io.viewportBelow = stepEl.map(function (el, i) {
var marginTop = -offsetMargin - stepOffsetHeight[i];
var marginBottom = offsetMargin - viewH + stepOffsetHeight[i] + pageH;
var rootMargin = marginTop + "px 0px " + marginBottom + "px 0px";
var options = {
root: null,
rootMargin: rootMargin,
threshold: 0
};
var obs = new IntersectionObserver(intersectStepBelow, options);
var options = { rootMargin: rootMargin };
// console.log(options);
var obs = new IntersectionObserver(intersectViewportBelow, options);
obs.observe(el);

@@ -593,16 +507,11 @@ return obs;

// jump into viewport
function updateViewportAboveIO() {
if (io.viewportAbove) { io.viewportAbove.forEach(function (d) { return d.disconnect(); }); }
io.viewportAbove = stepEl.map(function (el, i) {
var marginTop = stepOffsetTop[i];
var marginBottom = -(vh - offsetMargin + stepOffsetHeight[i]);
// look above for intersection
function updateStepAboveIO() {
io.stepAbove = stepEl.map(function (el, i) {
var marginTop = -offsetMargin + stepOffsetHeight[i];
var marginBottom = offsetMargin - viewH;
var rootMargin = marginTop + "px 0px " + marginBottom + "px 0px";
var options = {
root: null,
rootMargin: rootMargin,
threshold: 0
};
var obs = new IntersectionObserver(intersectViewportAbove, options);
var options = { rootMargin: rootMargin };
// console.log(options);
var obs = new IntersectionObserver(intersectStepAbove, options);
obs.observe(el);

@@ -613,16 +522,11 @@ return obs;

function updateViewportBelowIO() {
if (io.viewportBelow) { io.viewportBelow.forEach(function (d) { return d.disconnect(); }); }
io.viewportBelow = stepEl.map(function (el, i) {
var marginTop = -(offsetMargin + stepOffsetHeight[i]);
var marginBottom =
ph - stepOffsetTop[i] - stepOffsetHeight[i] - offsetMargin;
// look below for intersection
function updateStepBelowIO() {
io.stepAbove = stepEl.map(function (el, i) {
var marginTop = -offsetMargin;
var marginBottom = offsetMargin - viewH + stepOffsetHeight[i];
var rootMargin = marginTop + "px 0px " + marginBottom + "px 0px";
var options = {
root: null,
rootMargin: rootMargin,
threshold: 0
};
var obs = new IntersectionObserver(intersectViewportBelow, options);
var options = { rootMargin: rootMargin };
// console.log(options);
var obs = new IntersectionObserver(intersectStepBelow, options);
obs.observe(el);

@@ -635,16 +539,9 @@ return obs;

function updateStepProgressIO() {
if (io.stepProgress) { io.stepProgress.forEach(function (d) { return d.disconnect(); }); }
io.stepProgress = stepEl.map(function (el, i) {
var marginTop = stepOffsetHeight[i] - offsetMargin;
var marginBottom = -vh + offsetMargin;
var marginBottom = -viewH + offsetMargin;
var rootMargin = marginTop + "px 0px " + marginBottom + "px 0px";
var threshold = createThreshold(stepOffsetHeight[i]);
var options = {
root: null,
rootMargin: rootMargin,
threshold: threshold
};
var options = { rootMargin: rootMargin, threshold: threshold };
// console.log(options);
var obs = new IntersectionObserver(intersectStepProgress, options);

@@ -657,2 +554,4 @@ obs.observe(el);

function updateIO() {
OBSERVER_NAMES.forEach(disconnectObserver);
updateViewportAboveIO();

@@ -664,10 +563,5 @@ updateViewportBelowIO();

if (progressMode) { updateStepProgressIO(); }
if (containerEl && graphicEl) {
updateTopIO();
updateBottomIO();
}
}
// SETUP FUNCTIONS
/*** SETUP FUNCTIONS ***/

@@ -681,10 +575,9 @@ function indexSteps() {

direction: null,
state: null
state: null,
progress: 0
}); });
containerState = { direction: null, state: null };
}
function addDebug() {
if (debugMode) { setup({ id: id, stepEl: stepEl, offsetVal: offsetVal }); }
if (isDebug) { setup({ id: id, stepEl: stepEl, offsetVal: offsetVal }); }
}

@@ -695,4 +588,2 @@

S.setup = function (ref) {
var container = ref.container;
var graphic = ref.graphic;
var step = ref.step;

@@ -706,9 +597,7 @@ var offset = ref.offset; if ( offset === void 0 ) offset = 0.5;

id = generateId();
// elements
// create id unique to this scrollama instance
id = generateInstanceID();
stepEl = selectAll(step);
containerEl = container ? select(container) : null;
graphicEl = graphic ? select(graphic) : null;
// error if no step selected
if (!stepEl.length) {

@@ -720,3 +609,3 @@ console.error('scrollama error: no step elements');

// options
debugMode = debug;
isDebug = debug;
progressMode = progress;

@@ -736,3 +625,3 @@ preserveOrder = order;

handleResize();
handleEnable(true);
S.enable();
return S;

@@ -758,3 +647,3 @@ };

handleEnable(false);
Object.keys(callback).forEach(function (c) { return (callback[c] = null); });
Object.keys(cb).forEach(function (c) { return (cb[c] = null); });
Object.keys(io).forEach(function (i) { return (io[i] = null); });

@@ -771,27 +660,20 @@ };

S.onStepEnter = function (cb) {
callback.stepEnter = cb;
S.onStepEnter = function (f) {
if (typeof f === 'function') { cb.stepEnter = f; }
else { console.error('scrollama error: onStepEnter requires a function'); }
return S;
};
S.onStepExit = function (cb) {
callback.stepExit = cb;
S.onStepExit = function (f) {
if (typeof f === 'function') { cb.stepExit = f; }
else { console.error('scrollama error: onStepExit requires a function'); }
return S;
};
S.onStepProgress = function (cb) {
callback.stepProgress = cb;
S.onStepProgress = function (f) {
if (typeof f === 'function') { cb.stepProgress = f; }
else { console.error('scrollama error: onStepProgress requires a function'); }
return S;
};
S.onContainerEnter = function (cb) {
callback.containerEnter = cb;
return S;
};
S.onContainerExit = function (cb) {
callback.containerExit = cb;
return S;
};
return S;

@@ -798,0 +680,0 @@ }

2

build/scrollama.min.js

@@ -1,1 +0,1 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.scrollama=e()}(this,function(){"use strict";function t(t){for(var e=t.length,n=[],o=0;o<e;o+=1)n.push(t[o]);return n}function e(t){return t instanceof Element?t:"string"==typeof t?document.querySelector(t):null}function n(t){return"scrollama__debug-offset--"+t.id}function o(t){!function(t){var e=t.id,o=t.offsetVal,r=t.stepClass,i=document.createElement("div");i.setAttribute("id",n({id:e})),i.setAttribute("class","scrollama__debug-offset"),i.style.position="fixed",i.style.left="0",i.style.width="100%",i.style.height="0px",i.style.borderTop="2px dashed black",i.style.zIndex="9999";var s=document.createElement("p");s.innerText='".'+r+'" trigger: '+o,s.style.fontSize="12px",s.style.fontFamily="monospace",s.style.color="black",s.style.margin="0",s.style.padding="6px",i.appendChild(s),document.body.appendChild(i)}({id:t.id,offsetVal:t.offsetVal,stepClass:t.stepEl[0].getAttribute("class")})}function r(t){var e=t.id,o=(t.stepOffsetHeight,t.offsetMargin);t.offsetVal;!function(t){var e=t.id,o=t.offsetMargin,r=(t.offsetVal,n({id:e}));document.querySelector("#"+r).style.top=o+"px"}({id:e,offsetMargin:o})}function i(t){var e=t.id,n=t.index,o=t.state,r=function(t){return"scrollama__debug-step--"+t.id+"-"+t.i}({id:e,i:n}),i=document.querySelector("#"+r+"_above"),s=document.querySelector("#"+r+"_below"),c="enter"===o?"block":"none";i&&(i.style.display=c),s&&(s.style.display=c)}return function(){var n=1,s={},c={},u=null,a=null,f=null,l=null,p=0,d=0,v=0,g=0,h=null,b=null,x=null,m=!1,w=!1,E=!1,y=!1,M=0,A=!1,I=!1,O=null,C=null,P=-1,B=null,H=[];function S(t){var e=0;if(t.offsetParent)do{e+=t.offsetTop,t=t.offsetParent}while(t);return e<0?0:e}function _(t){return+t.getAttribute("data-scrollama-index")}function R(){window.pageYOffset>P?B="down":window.pageYOffset<P&&(B="up"),P=window.pageYOffset}function V(){var t,e;v=window.innerHeight,t=document.body,e=document.documentElement,g=Math.max(t.scrollHeight,t.offsetHeight,e.clientHeight,e.scrollHeight,e.offsetHeight),x=a?a.getBoundingClientRect():null,d=p*v,h=f?f.map(function(t){return t.offsetHeight}):[],b=f?f.map(S):[],w&&m&&W(),E&&r({id:l,stepOffsetHeight:h,offsetMargin:d,offsetVal:p})}function k(t){t&&!w?(m&&W(),w=!0):t||(c.top&&c.top.disconnect(),c.bottom&&c.bottom.disconnect(),c.stepAbove&&c.stepAbove.forEach(function(t){return t.disconnect()}),c.stepBelow&&c.stepBelow.forEach(function(t){return t.disconnect()}),c.stepProgress&&c.stepProgress.forEach(function(t){return t.disconnect()}),c.viewportAbove&&c.viewportAbove.forEach(function(t){return t.disconnect()}),c.viewportBelow&&c.viewportBelow.forEach(function(t){return t.disconnect()}),w=!1)}function q(t,e){if("above"===e)for(var n=0;n<t;n++){var o=O[n];"enter"===o.state&&j(f[n],"down"),"up"===o.direction&&(T(f[n],"down",!1),j(f[n],"down"))}else if("below"===e)for(var r=O.length-1;r>t;r--){var i=O[r];"enter"===i.state&&j(f[r],"up"),"down"===i.direction&&(T(f[r],"up",!1),j(f[r],"up"))}}function T(t,e,n){void 0===n&&(n=!0);var o=_(t),r={element:t,index:o,direction:e};O[o].direction=e,O[o].state="enter",A&&n&&"down"===e&&q(o,"above"),A&&n&&"up"===e&&q(o,"below"),s.stepEnter&&"function"==typeof s.stepEnter&&!H[o]&&(s.stepEnter(r,O),E&&i({id:l,index:o,state:"enter"}),I&&(H[o]=!0)),y&&z(t,"down"===e?0:1)}function j(t,e){var n=_(t),o={element:t,index:n,direction:e};O[n].direction=e,O[n].state="exit",y&&z(t,"down"===e?1:0),s.stepExit&&"function"==typeof s.stepExit&&(s.stepExit(o,O),E&&i({id:l,index:n,state:"exit"}))}function z(t,e){var n={element:t,index:_(t),progress:e};s.stepProgress&&"function"==typeof s.stepProgress&&s.stepProgress(n)}function N(){var t={direction:B};C.direction=B,C.state="enter",s.containerEnter&&"function"==typeof s.containerEnter&&s.containerEnter(t)}function Y(){var t={direction:B};C.direction=B,C.state="exit",s.containerExit&&"function"==typeof s.containerExit&&s.containerExit(t)}function F(t){R(),t.forEach(function(t){var e=t.isIntersecting,o=t.boundingClientRect,r=t.target,i=o.bottom,s=o.height,c=i-d,u=_(r),a=O[u];c>=-n&&(e&&"down"===B&&"enter"!==a.state?T(r,B):e||"up"!==B||"enter"!==a.state?!e&&c>=s&&"down"===B&&"enter"===a.state&&j(r,B):j(r,B))})}function D(t){R(),t.forEach(function(t){var e=t.isIntersecting,o=t.boundingClientRect,r=t.target,i=o.bottom,s=o.height,c=i-d,u=_(r),a=O[u];c>=-n&&c<s&&e&&"up"===B&&"enter"!==a.state?T(r,B):c<=n&&!e&&"down"===B&&"enter"===a.state&&j(r,B)})}function L(t){R(),t.forEach(function(t){var e=t.isIntersecting,n=t.target,o=_(n),r=O[o];e&&"down"===B&&"enter"!==r.state&&"down"!==r.direction&&(T(n,"down"),j(n,"down"))})}function G(t){R(),t.forEach(function(t){var e=t.isIntersecting,n=t.target,o=_(n),r=O[o];e&&"up"===B&&"enter"!==r.state&&"up"!==r.direction&&(T(n,"up"),j(n,"up"))})}function J(t){R(),t.forEach(function(t){var e=t.isIntersecting,o=t.intersectionRatio,r=t.boundingClientRect,i=t.target,s=r.bottom;e&&s-d>=-n&&z(i,+o.toFixed(3))})}function K(t){R();var e=t[0],o=e.isIntersecting,r=e.boundingClientRect;r.top,r.bottom>-n&&(o?N():"enter"===C.state&&Y())}function Q(t){R();var e=t[0],o=e.isIntersecting;e.boundingClientRect.top<n&&(o?N():"enter"===C.state&&Y())}function U(){c.stepProgress&&c.stepProgress.forEach(function(t){return t.disconnect()}),c.stepProgress=f.map(function(t,e){var n=h[e]-d+"px 0px "+(-v+d)+"px 0px",o=function(t){for(var e=Math.ceil(t/M),n=[],o=1/e,r=0;r<e;r++)n.push(r*o);return n}(h[e]),r=new IntersectionObserver(J,{root:null,rootMargin:n,threshold:o});return r.observe(t),r})}function W(){c.viewportAbove&&c.viewportAbove.forEach(function(t){return t.disconnect()}),c.viewportAbove=f.map(function(t,e){var n=b[e],o=-(v-d+h[e]),r=new IntersectionObserver(L,{root:null,rootMargin:n+"px 0px "+o+"px 0px",threshold:0});return r.observe(t),r}),c.viewportBelow&&c.viewportBelow.forEach(function(t){return t.disconnect()}),c.viewportBelow=f.map(function(t,e){var n=-(d+h[e]),o=g-b[e]-h[e]-d,r=new IntersectionObserver(G,{root:null,rootMargin:n+"px 0px "+o+"px 0px",threshold:0});return r.observe(t),r}),c.stepAbove&&c.stepAbove.forEach(function(t){return t.disconnect()}),c.stepAbove=f.map(function(t,e){var n=h[e],o=new IntersectionObserver(F,{root:null,rootMargin:n+"px 0px "+(-v+d)+"px 0px",threshold:0});return o.observe(t),o}),c.stepBelow&&c.stepBelow.forEach(function(t){return t.disconnect()}),c.stepBelow=f.map(function(t,e){var n=-d,o=g-v+h[e]+d,r=new IntersectionObserver(D,{root:null,rootMargin:n+"px 0px "+o+"px 0px",threshold:0});return r.observe(t),r}),y&&U(),u&&a&&(function(){c.top&&c.top.unobserve(u);var t={root:null,rootMargin:v+"px 0px -"+v+"px 0px",threshold:0};c.top=new IntersectionObserver(K,t),c.top.observe(u)}(),function(){c.bottom&&c.bottom.unobserve(u);var t={root:null,rootMargin:"-"+x.height+"px 0px "+x.height+"px 0px",threshold:0};c.bottom=new IntersectionObserver(Q,t),c.bottom.observe(u)}())}var X={};return X.setup=function(n){var r=n.container,i=n.graphic,s=n.step,c=n.offset;void 0===c&&(c=.5);var d=n.progress;void 0===d&&(d=!1);var v=n.threshold;void 0===v&&(v=4);var g=n.debug;void 0===g&&(g=!1);var h=n.order;void 0===h&&(h=!0);var b,x,w,P,B,H=n.once;return void 0===H&&(H=!1),x=(b="abcdefghijklmnopqrstuv").length,w=(new Date).getTime(),l=""+[0,0,0].map(function(t){return b[Math.floor(Math.random()*x)]}).join("")+w,P=s,void 0===B&&(B=document),f="string"==typeof P?t(B.querySelectorAll(P)):P instanceof Element?t([P]):P instanceof NodeList?t(P):P instanceof Array?P:[],u=r?e(r):null,a=i?e(i):null,f.length?(E=g,y=d,A=h,I=H,X.offsetTrigger(c),M=Math.max(1,+v),m=!0,E&&o({id:l,stepEl:f,offsetVal:p}),f.forEach(function(t,e){return t.setAttribute("data-scrollama-index",e)}),O=f.map(function(){return{direction:null,state:null}}),C={direction:null,state:null},V(),k(!0),X):(console.error("scrollama error: no step elements"),X)},X.resize=function(){return V(),X},X.enable=function(){return k(!0),X},X.disable=function(){return k(!1),X},X.destroy=function(){k(!1),Object.keys(s).forEach(function(t){return s[t]=null}),Object.keys(c).forEach(function(t){return c[t]=null})},X.offsetTrigger=function(t){return t&&!isNaN(t)?(p=Math.min(Math.max(0,t),1),X):p},X.onStepEnter=function(t){return s.stepEnter=t,X},X.onStepExit=function(t){return s.stepExit=t,X},X.onStepProgress=function(t){return s.stepProgress=t,X},X.onContainerEnter=function(t){return s.containerEnter=t,X},X.onContainerExit=function(t){return s.containerExit=t,X},X}});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.scrollama=t()}(this,function(){"use strict";function e(e){for(var t=e.length,n=[],r=0;r<t;r+=1)n.push(e[r]);return n}function t(e){return"scrollama__debug-offset--"+e.id}function n(e){!function(e){var n=e.id,r=e.offsetVal,o=e.stepClass,i=document.createElement("div");i.setAttribute("id",t({id:n})),i.setAttribute("class","scrollama__debug-offset"),i.style.position="fixed",i.style.left="0",i.style.width="100%",i.style.height="0px",i.style.borderTop="2px dashed black",i.style.zIndex="9999";var s=document.createElement("p");s.innerText='".'+o+'" trigger: '+r,s.style.fontSize="12px",s.style.fontFamily="monospace",s.style.color="black",s.style.margin="0",s.style.padding="6px",i.appendChild(s),document.body.appendChild(i)}({id:e.id,offsetVal:e.offsetVal,stepClass:e.stepEl[0].getAttribute("class")})}function r(e){var n=e.id,r=(e.stepOffsetHeight,e.offsetMargin);e.offsetVal;!function(e){var n=e.id,r=e.offsetMargin,o=(e.offsetVal,t({id:n}));document.querySelector("#"+o).style.top=r+"px"}({id:n,offsetMargin:r})}function o(e){var t=e.id,n=e.index,r=e.state,o=function(e){return"scrollama__debug-step--"+e.id+"-"+e.i}({id:t,i:n}),i=document.querySelector("#"+o+"_above"),s=document.querySelector("#"+o+"_below"),a="enter"===r?"block":"none";i&&(i.style.display=a),s&&(s.style.display=a)}return function(){var t=["stepAbove","stepBelow","stepProgress","viewportAbove","viewportBelow"],i={stepEnter:function(){},stepExit:function(){},stepProgress:function(){}},s={},a=null,f=[],u=[],c=[],d=[],p=0,l=0,v=0,g=0,m=0,b=0,x=!1,w=!1,h=!1,y=!1,E=!1,M=!1,A="down",O=[];function I(e){var t=0;if(e.offsetParent)do{t+=e.offsetTop,e=e.offsetParent}while(e);return t<0?0:t}function S(e){return+e.getAttribute("data-scrollama-index")}function H(){window.pageYOffset>m?A="down":window.pageYOffset<m&&(A="up"),m=window.pageYOffset}function P(e){s[e]&&s[e].forEach(function(e){return e.disconnect()})}function q(){var e,t;v=window.innerHeight,e=document.body,t=document.documentElement,g=Math.max(e.scrollHeight,e.offsetHeight,t.clientHeight,t.scrollHeight,t.offsetHeight),l=p*v,x&&(u=f.map(function(e){return e.offsetHeight}),c=f.map(I),w&&F()),h&&r({id:a,stepOffsetHeight:u,offsetMargin:l,offsetVal:p})}function _(e){if(e&&!w)return x&&F(),w=!0,!0;t.forEach(P),w=!1}function C(e,t){var n=S(e);void 0!==t&&(d[n].progress=t);var r={element:e,index:n,progress:d[n].progress};"enter"===d[n].state&&i.stepProgress(r)}function V(e,t){if("above"===t)for(var n=0;n<e;n++){var r=d[n];"enter"!==r.state&&"down"!==r.direction?(k(f[n],"down",!1),j(f[n],"down")):"enter"===r.state&&j(f[n],"down")}else if("below"===t)for(var o=d.length-1;o>e;o--){var i=d[o];"enter"===i.state&&j(f[o],"up"),"down"===i.direction&&(k(f[o],"up",!1),j(f[o],"up"))}}function k(e,t,n){void 0===n&&(n=!0);var r=S(e),s={element:e,index:r,direction:t};d[r].direction=t,d[r].state="enter",E&&n&&"down"===t&&V(r,"above"),E&&n&&"up"===t&&V(r,"below"),i.stepEnter&&!O[r]&&(i.stepEnter(s,d),h&&o({id:a,index:r,state:"enter"}),M&&(O[r]=!0)),y&&C(e)}function j(e,t){var n=S(e),r={element:e,index:n,direction:t};y&&("down"===t&&d[n].progress<1?C(e,1):"up"===t&&d[n].progress>0&&C(e,0)),d[n].direction=t,d[n].state="exit",i.stepExit(r,d),h&&o({id:a,index:n,state:"exit"})}function T(e){var t=e[0];H();var n=t.isIntersecting,r=t.boundingClientRect,o=t.target,i=r.top,s=r.bottom,a=i-l,f=s-l,u=S(o),c=d[u];n&&a<=0&&f>=0&&"down"===A&&"enter"!==c.state&&k(o,A),!n&&a>0&&"up"===A&&"enter"===c.state&&j(o,A)}function R(e){var t=e[0];H();var n=t.isIntersecting,r=t.boundingClientRect,o=t.target,i=r.top,s=r.bottom,a=i-l,f=s-l,u=S(o),c=d[u];n&&a<=0&&f>=0&&"up"===A&&"enter"!==c.state&&k(o,A),!n&&f<0&&"down"===A&&"enter"===c.state&&j(o,A)}function z(e){var t=e[0];H();var n=t.isIntersecting,r=t.target,o=S(r),i=d[o];n&&"down"===A&&"down"!==i.direction&&"enter"!==i.state&&(k(r,"down"),j(r,"down"))}function B(e){var t=e[0];H();var n=t.isIntersecting,r=t.target,o=S(r),i=d[o];n&&"up"===A&&"down"===i.direction&&"enter"!==i.state&&(k(r,"up"),j(r,"up"))}function N(e){var t=e[0];H();var n=t.isIntersecting,r=t.intersectionRatio,o=t.boundingClientRect,i=t.target,s=o.bottom;n&&s-l>=0&&C(i,+r.toFixed(3))}function Y(){s.stepProgress=f.map(function(e,t){var n=u[t]-l+"px 0px "+(-v+l)+"px 0px",r=function(e){for(var t=Math.ceil(e/b),n=[],r=1/t,o=0;o<t;o++)n.push(o*r);return n}(u[t]),o=new IntersectionObserver(N,{rootMargin:n,threshold:r});return o.observe(e),o})}function F(){t.forEach(P),s.viewportAbove=f.map(function(e,t){var n=g-c[t],r=l-v-u[t],o=new IntersectionObserver(z,{rootMargin:n+"px 0px "+r+"px 0px"});return o.observe(e),o}),s.viewportBelow=f.map(function(e,t){var n=-l-u[t],r=l-v+u[t]+g,o=new IntersectionObserver(B,{rootMargin:n+"px 0px "+r+"px 0px"});return o.observe(e),o}),s.stepAbove=f.map(function(e,t){var n=-l+u[t],r=new IntersectionObserver(T,{rootMargin:n+"px 0px "+(l-v)+"px 0px"});return r.observe(e),r}),s.stepAbove=f.map(function(e,t){var n=-l,r=l-v+u[t],o=new IntersectionObserver(R,{rootMargin:n+"px 0px "+r+"px 0px"});return o.observe(e),o}),y&&Y()}var D={};return D.setup=function(t){var r=t.step,o=t.offset;void 0===o&&(o=.5);var i=t.progress;void 0===i&&(i=!1);var s=t.threshold;void 0===s&&(s=4);var u=t.debug;void 0===u&&(u=!1);var c=t.order;void 0===c&&(c=!0);var l,v,g,m,w,A=t.once;return void 0===A&&(A=!1),v=(l="abcdefghijklmnopqrstuv").length,g=Date.now(),a=""+[0,0,0].map(function(e){return l[Math.floor(Math.random()*v)]}).join("")+g,m=r,void 0===w&&(w=document),(f="string"==typeof m?e(w.querySelectorAll(m)):m instanceof Element?e([m]):m instanceof NodeList?e(m):m instanceof Array?m:[]).length?(h=u,y=i,E=c,M=A,D.offsetTrigger(o),b=Math.max(1,+s),x=!0,h&&n({id:a,stepEl:f,offsetVal:p}),f.forEach(function(e,t){return e.setAttribute("data-scrollama-index",t)}),d=f.map(function(){return{direction:null,state:null,progress:0}}),q(),D.enable(),D):(console.error("scrollama error: no step elements"),D)},D.resize=function(){return q(),D},D.enable=function(){return _(!0),D},D.disable=function(){return _(!1),D},D.destroy=function(){_(!1),Object.keys(i).forEach(function(e){return i[e]=null}),Object.keys(s).forEach(function(e){return s[e]=null})},D.offsetTrigger=function(e){return e&&!isNaN(e)?(p=Math.min(Math.max(0,e),1),D):p},D.onStepEnter=function(e){return"function"==typeof e?i.stepEnter=e:console.error("scrollama error: onStepEnter requires a function"),D},D.onStepExit=function(e){return"function"==typeof e?i.stepExit=e:console.error("scrollama error: onStepExit requires a function"),D},D.onStepProgress=function(e){return"function"==typeof e?i.stepProgress=e:console.error("scrollama error: onStepProgress requires a function"),D},D}});

@@ -1,1 +0,1 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.scrollama=e()}(this,function(){"use strict";function t(t){for(var e=t.length,n=[],o=0;o<e;o+=1)n.push(t[o]);return n}function e(t){return t instanceof Element?t:"string"==typeof t?document.querySelector(t):null}function n(t){return"scrollama__debug-offset--"+t.id}function o(t){!function(t){var e=t.id,o=t.offsetVal,r=t.stepClass,i=document.createElement("div");i.setAttribute("id",n({id:e})),i.setAttribute("class","scrollama__debug-offset"),i.style.position="fixed",i.style.left="0",i.style.width="100%",i.style.height="0px",i.style.borderTop="2px dashed black",i.style.zIndex="9999";var s=document.createElement("p");s.innerText='".'+r+'" trigger: '+o,s.style.fontSize="12px",s.style.fontFamily="monospace",s.style.color="black",s.style.margin="0",s.style.padding="6px",i.appendChild(s),document.body.appendChild(i)}({id:t.id,offsetVal:t.offsetVal,stepClass:t.stepEl[0].getAttribute("class")})}function r(t){var e=t.id,o=(t.stepOffsetHeight,t.offsetMargin);t.offsetVal;!function(t){var e=t.id,o=t.offsetMargin,r=(t.offsetVal,n({id:e}));document.querySelector("#"+r).style.top=o+"px"}({id:e,offsetMargin:o})}function i(t){var e=t.id,n=t.index,o=t.state,r=function(t){return"scrollama__debug-step--"+t.id+"-"+t.i}({id:e,i:n}),i=document.querySelector("#"+r+"_above"),s=document.querySelector("#"+r+"_below"),c="enter"===o?"block":"none";i&&(i.style.display=c),s&&(s.style.display=c)}return function(){var n=1,s={},c={},u=null,a=null,f=null,l=null,p=0,d=0,v=0,g=0,h=null,b=null,x=null,m=!1,w=!1,E=!1,y=!1,M=0,A=!1,I=!1,O=null,C=null,P=-1,B=null,H=[];function S(t){var e=0;if(t.offsetParent)do{e+=t.offsetTop,t=t.offsetParent}while(t);return e<0?0:e}function _(t){return+t.getAttribute("data-scrollama-index")}function R(){window.pageYOffset>P?B="down":window.pageYOffset<P&&(B="up"),P=window.pageYOffset}function V(){var t,e;v=window.innerHeight,t=document.body,e=document.documentElement,g=Math.max(t.scrollHeight,t.offsetHeight,e.clientHeight,e.scrollHeight,e.offsetHeight),x=a?a.getBoundingClientRect():null,d=p*v,h=f?f.map(function(t){return t.offsetHeight}):[],b=f?f.map(S):[],w&&m&&W(),E&&r({id:l,stepOffsetHeight:h,offsetMargin:d,offsetVal:p})}function k(t){t&&!w?(m&&W(),w=!0):t||(c.top&&c.top.disconnect(),c.bottom&&c.bottom.disconnect(),c.stepAbove&&c.stepAbove.forEach(function(t){return t.disconnect()}),c.stepBelow&&c.stepBelow.forEach(function(t){return t.disconnect()}),c.stepProgress&&c.stepProgress.forEach(function(t){return t.disconnect()}),c.viewportAbove&&c.viewportAbove.forEach(function(t){return t.disconnect()}),c.viewportBelow&&c.viewportBelow.forEach(function(t){return t.disconnect()}),w=!1)}function q(t,e){if("above"===e)for(var n=0;n<t;n++){var o=O[n];"enter"===o.state&&j(f[n],"down"),"up"===o.direction&&(T(f[n],"down",!1),j(f[n],"down"))}else if("below"===e)for(var r=O.length-1;r>t;r--){var i=O[r];"enter"===i.state&&j(f[r],"up"),"down"===i.direction&&(T(f[r],"up",!1),j(f[r],"up"))}}function T(t,e,n){void 0===n&&(n=!0);var o=_(t),r={element:t,index:o,direction:e};O[o].direction=e,O[o].state="enter",A&&n&&"down"===e&&q(o,"above"),A&&n&&"up"===e&&q(o,"below"),s.stepEnter&&"function"==typeof s.stepEnter&&!H[o]&&(s.stepEnter(r,O),E&&i({id:l,index:o,state:"enter"}),I&&(H[o]=!0)),y&&z(t,"down"===e?0:1)}function j(t,e){var n=_(t),o={element:t,index:n,direction:e};O[n].direction=e,O[n].state="exit",y&&z(t,"down"===e?1:0),s.stepExit&&"function"==typeof s.stepExit&&(s.stepExit(o,O),E&&i({id:l,index:n,state:"exit"}))}function z(t,e){var n={element:t,index:_(t),progress:e};s.stepProgress&&"function"==typeof s.stepProgress&&s.stepProgress(n)}function N(){var t={direction:B};C.direction=B,C.state="enter",s.containerEnter&&"function"==typeof s.containerEnter&&s.containerEnter(t)}function Y(){var t={direction:B};C.direction=B,C.state="exit",s.containerExit&&"function"==typeof s.containerExit&&s.containerExit(t)}function F(t){R(),t.forEach(function(t){var e=t.isIntersecting,o=t.boundingClientRect,r=t.target,i=o.bottom,s=o.height,c=i-d,u=_(r),a=O[u];c>=-n&&(e&&"down"===B&&"enter"!==a.state?T(r,B):e||"up"!==B||"enter"!==a.state?!e&&c>=s&&"down"===B&&"enter"===a.state&&j(r,B):j(r,B))})}function D(t){R(),t.forEach(function(t){var e=t.isIntersecting,o=t.boundingClientRect,r=t.target,i=o.bottom,s=o.height,c=i-d,u=_(r),a=O[u];c>=-n&&c<s&&e&&"up"===B&&"enter"!==a.state?T(r,B):c<=n&&!e&&"down"===B&&"enter"===a.state&&j(r,B)})}function L(t){R(),t.forEach(function(t){var e=t.isIntersecting,n=t.target,o=_(n),r=O[o];e&&"down"===B&&"enter"!==r.state&&"down"!==r.direction&&(T(n,"down"),j(n,"down"))})}function G(t){R(),t.forEach(function(t){var e=t.isIntersecting,n=t.target,o=_(n),r=O[o];e&&"up"===B&&"enter"!==r.state&&"up"!==r.direction&&(T(n,"up"),j(n,"up"))})}function J(t){R(),t.forEach(function(t){var e=t.isIntersecting,o=t.intersectionRatio,r=t.boundingClientRect,i=t.target,s=r.bottom;e&&s-d>=-n&&z(i,+o.toFixed(3))})}function K(t){R();var e=t[0],o=e.isIntersecting,r=e.boundingClientRect;r.top,r.bottom>-n&&(o?N():"enter"===C.state&&Y())}function Q(t){R();var e=t[0],o=e.isIntersecting;e.boundingClientRect.top<n&&(o?N():"enter"===C.state&&Y())}function U(){c.stepProgress&&c.stepProgress.forEach(function(t){return t.disconnect()}),c.stepProgress=f.map(function(t,e){var n=h[e]-d+"px 0px "+(-v+d)+"px 0px",o=function(t){for(var e=Math.ceil(t/M),n=[],o=1/e,r=0;r<e;r++)n.push(r*o);return n}(h[e]),r=new IntersectionObserver(J,{root:null,rootMargin:n,threshold:o});return r.observe(t),r})}function W(){c.viewportAbove&&c.viewportAbove.forEach(function(t){return t.disconnect()}),c.viewportAbove=f.map(function(t,e){var n=b[e],o=-(v-d+h[e]),r=new IntersectionObserver(L,{root:null,rootMargin:n+"px 0px "+o+"px 0px",threshold:0});return r.observe(t),r}),c.viewportBelow&&c.viewportBelow.forEach(function(t){return t.disconnect()}),c.viewportBelow=f.map(function(t,e){var n=-(d+h[e]),o=g-b[e]-h[e]-d,r=new IntersectionObserver(G,{root:null,rootMargin:n+"px 0px "+o+"px 0px",threshold:0});return r.observe(t),r}),c.stepAbove&&c.stepAbove.forEach(function(t){return t.disconnect()}),c.stepAbove=f.map(function(t,e){var n=h[e],o=new IntersectionObserver(F,{root:null,rootMargin:n+"px 0px "+(-v+d)+"px 0px",threshold:0});return o.observe(t),o}),c.stepBelow&&c.stepBelow.forEach(function(t){return t.disconnect()}),c.stepBelow=f.map(function(t,e){var n=-d,o=g-v+h[e]+d,r=new IntersectionObserver(D,{root:null,rootMargin:n+"px 0px "+o+"px 0px",threshold:0});return r.observe(t),r}),y&&U(),u&&a&&(function(){c.top&&c.top.unobserve(u);var t={root:null,rootMargin:v+"px 0px -"+v+"px 0px",threshold:0};c.top=new IntersectionObserver(K,t),c.top.observe(u)}(),function(){c.bottom&&c.bottom.unobserve(u);var t={root:null,rootMargin:"-"+x.height+"px 0px "+x.height+"px 0px",threshold:0};c.bottom=new IntersectionObserver(Q,t),c.bottom.observe(u)}())}var X={};return X.setup=function(n){var r=n.container,i=n.graphic,s=n.step,c=n.offset;void 0===c&&(c=.5);var d=n.progress;void 0===d&&(d=!1);var v=n.threshold;void 0===v&&(v=4);var g=n.debug;void 0===g&&(g=!1);var h=n.order;void 0===h&&(h=!0);var b,x,w,P,B,H=n.once;return void 0===H&&(H=!1),x=(b="abcdefghijklmnopqrstuv").length,w=(new Date).getTime(),l=""+[0,0,0].map(function(t){return b[Math.floor(Math.random()*x)]}).join("")+w,P=s,void 0===B&&(B=document),f="string"==typeof P?t(B.querySelectorAll(P)):P instanceof Element?t([P]):P instanceof NodeList?t(P):P instanceof Array?P:[],u=r?e(r):null,a=i?e(i):null,f.length?(E=g,y=d,A=h,I=H,X.offsetTrigger(c),M=Math.max(1,+v),m=!0,E&&o({id:l,stepEl:f,offsetVal:p}),f.forEach(function(t,e){return t.setAttribute("data-scrollama-index",e)}),O=f.map(function(){return{direction:null,state:null}}),C={direction:null,state:null},V(),k(!0),X):(console.error("scrollama error: no step elements"),X)},X.resize=function(){return V(),X},X.enable=function(){return k(!0),X},X.disable=function(){return k(!1),X},X.destroy=function(){k(!1),Object.keys(s).forEach(function(t){return s[t]=null}),Object.keys(c).forEach(function(t){return c[t]=null})},X.offsetTrigger=function(t){return t&&!isNaN(t)?(p=Math.min(Math.max(0,t),1),X):p},X.onStepEnter=function(t){return s.stepEnter=t,X},X.onStepExit=function(t){return s.stepExit=t,X},X.onStepProgress=function(t){return s.stepProgress=t,X},X.onContainerEnter=function(t){return s.containerEnter=t,X},X.onContainerExit=function(t){return s.containerExit=t,X},X}});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.scrollama=t()}(this,function(){"use strict";function e(e){for(var t=e.length,n=[],r=0;r<t;r+=1)n.push(e[r]);return n}function t(e){return"scrollama__debug-offset--"+e.id}function n(e){!function(e){var n=e.id,r=e.offsetVal,o=e.stepClass,i=document.createElement("div");i.setAttribute("id",t({id:n})),i.setAttribute("class","scrollama__debug-offset"),i.style.position="fixed",i.style.left="0",i.style.width="100%",i.style.height="0px",i.style.borderTop="2px dashed black",i.style.zIndex="9999";var s=document.createElement("p");s.innerText='".'+o+'" trigger: '+r,s.style.fontSize="12px",s.style.fontFamily="monospace",s.style.color="black",s.style.margin="0",s.style.padding="6px",i.appendChild(s),document.body.appendChild(i)}({id:e.id,offsetVal:e.offsetVal,stepClass:e.stepEl[0].getAttribute("class")})}function r(e){var n=e.id,r=(e.stepOffsetHeight,e.offsetMargin);e.offsetVal;!function(e){var n=e.id,r=e.offsetMargin,o=(e.offsetVal,t({id:n}));document.querySelector("#"+o).style.top=r+"px"}({id:n,offsetMargin:r})}function o(e){var t=e.id,n=e.index,r=e.state,o=function(e){return"scrollama__debug-step--"+e.id+"-"+e.i}({id:t,i:n}),i=document.querySelector("#"+o+"_above"),s=document.querySelector("#"+o+"_below"),a="enter"===r?"block":"none";i&&(i.style.display=a),s&&(s.style.display=a)}return function(){var t=["stepAbove","stepBelow","stepProgress","viewportAbove","viewportBelow"],i={stepEnter:function(){},stepExit:function(){},stepProgress:function(){}},s={},a=null,f=[],u=[],c=[],d=[],p=0,l=0,v=0,g=0,m=0,b=0,x=!1,w=!1,h=!1,y=!1,E=!1,M=!1,A="down",O=[];function I(e){var t=0;if(e.offsetParent)do{t+=e.offsetTop,e=e.offsetParent}while(e);return t<0?0:t}function S(e){return+e.getAttribute("data-scrollama-index")}function H(){window.pageYOffset>m?A="down":window.pageYOffset<m&&(A="up"),m=window.pageYOffset}function P(e){s[e]&&s[e].forEach(function(e){return e.disconnect()})}function q(){var e,t;v=window.innerHeight,e=document.body,t=document.documentElement,g=Math.max(e.scrollHeight,e.offsetHeight,t.clientHeight,t.scrollHeight,t.offsetHeight),l=p*v,x&&(u=f.map(function(e){return e.offsetHeight}),c=f.map(I),w&&F()),h&&r({id:a,stepOffsetHeight:u,offsetMargin:l,offsetVal:p})}function _(e){if(e&&!w)return x&&F(),w=!0,!0;t.forEach(P),w=!1}function C(e,t){var n=S(e);void 0!==t&&(d[n].progress=t);var r={element:e,index:n,progress:d[n].progress};"enter"===d[n].state&&i.stepProgress(r)}function V(e,t){if("above"===t)for(var n=0;n<e;n++){var r=d[n];"enter"!==r.state&&"down"!==r.direction?(k(f[n],"down",!1),j(f[n],"down")):"enter"===r.state&&j(f[n],"down")}else if("below"===t)for(var o=d.length-1;o>e;o--){var i=d[o];"enter"===i.state&&j(f[o],"up"),"down"===i.direction&&(k(f[o],"up",!1),j(f[o],"up"))}}function k(e,t,n){void 0===n&&(n=!0);var r=S(e),s={element:e,index:r,direction:t};d[r].direction=t,d[r].state="enter",E&&n&&"down"===t&&V(r,"above"),E&&n&&"up"===t&&V(r,"below"),i.stepEnter&&!O[r]&&(i.stepEnter(s,d),h&&o({id:a,index:r,state:"enter"}),M&&(O[r]=!0)),y&&C(e)}function j(e,t){var n=S(e),r={element:e,index:n,direction:t};y&&("down"===t&&d[n].progress<1?C(e,1):"up"===t&&d[n].progress>0&&C(e,0)),d[n].direction=t,d[n].state="exit",i.stepExit(r,d),h&&o({id:a,index:n,state:"exit"})}function T(e){var t=e[0];H();var n=t.isIntersecting,r=t.boundingClientRect,o=t.target,i=r.top,s=r.bottom,a=i-l,f=s-l,u=S(o),c=d[u];n&&a<=0&&f>=0&&"down"===A&&"enter"!==c.state&&k(o,A),!n&&a>0&&"up"===A&&"enter"===c.state&&j(o,A)}function R(e){var t=e[0];H();var n=t.isIntersecting,r=t.boundingClientRect,o=t.target,i=r.top,s=r.bottom,a=i-l,f=s-l,u=S(o),c=d[u];n&&a<=0&&f>=0&&"up"===A&&"enter"!==c.state&&k(o,A),!n&&f<0&&"down"===A&&"enter"===c.state&&j(o,A)}function z(e){var t=e[0];H();var n=t.isIntersecting,r=t.target,o=S(r),i=d[o];n&&"down"===A&&"down"!==i.direction&&"enter"!==i.state&&(k(r,"down"),j(r,"down"))}function B(e){var t=e[0];H();var n=t.isIntersecting,r=t.target,o=S(r),i=d[o];n&&"up"===A&&"down"===i.direction&&"enter"!==i.state&&(k(r,"up"),j(r,"up"))}function N(e){var t=e[0];H();var n=t.isIntersecting,r=t.intersectionRatio,o=t.boundingClientRect,i=t.target,s=o.bottom;n&&s-l>=0&&C(i,+r.toFixed(3))}function Y(){s.stepProgress=f.map(function(e,t){var n=u[t]-l+"px 0px "+(-v+l)+"px 0px",r=function(e){for(var t=Math.ceil(e/b),n=[],r=1/t,o=0;o<t;o++)n.push(o*r);return n}(u[t]),o=new IntersectionObserver(N,{rootMargin:n,threshold:r});return o.observe(e),o})}function F(){t.forEach(P),s.viewportAbove=f.map(function(e,t){var n=g-c[t],r=l-v-u[t],o=new IntersectionObserver(z,{rootMargin:n+"px 0px "+r+"px 0px"});return o.observe(e),o}),s.viewportBelow=f.map(function(e,t){var n=-l-u[t],r=l-v+u[t]+g,o=new IntersectionObserver(B,{rootMargin:n+"px 0px "+r+"px 0px"});return o.observe(e),o}),s.stepAbove=f.map(function(e,t){var n=-l+u[t],r=new IntersectionObserver(T,{rootMargin:n+"px 0px "+(l-v)+"px 0px"});return r.observe(e),r}),s.stepAbove=f.map(function(e,t){var n=-l,r=l-v+u[t],o=new IntersectionObserver(R,{rootMargin:n+"px 0px "+r+"px 0px"});return o.observe(e),o}),y&&Y()}var D={};return D.setup=function(t){var r=t.step,o=t.offset;void 0===o&&(o=.5);var i=t.progress;void 0===i&&(i=!1);var s=t.threshold;void 0===s&&(s=4);var u=t.debug;void 0===u&&(u=!1);var c=t.order;void 0===c&&(c=!0);var l,v,g,m,w,A=t.once;return void 0===A&&(A=!1),v=(l="abcdefghijklmnopqrstuv").length,g=Date.now(),a=""+[0,0,0].map(function(e){return l[Math.floor(Math.random()*v)]}).join("")+g,m=r,void 0===w&&(w=document),(f="string"==typeof m?e(w.querySelectorAll(m)):m instanceof Element?e([m]):m instanceof NodeList?e(m):m instanceof Array?m:[]).length?(h=u,y=i,E=c,M=A,D.offsetTrigger(o),b=Math.max(1,+s),x=!0,h&&n({id:a,stepEl:f,offsetVal:p}),f.forEach(function(e,t){return e.setAttribute("data-scrollama-index",t)}),d=f.map(function(){return{direction:null,state:null,progress:0}}),q(),D.enable(),D):(console.error("scrollama error: no step elements"),D)},D.resize=function(){return q(),D},D.enable=function(){return _(!0),D},D.disable=function(){return _(!1),D},D.destroy=function(){_(!1),Object.keys(i).forEach(function(e){return i[e]=null}),Object.keys(s).forEach(function(e){return s[e]=null})},D.offsetTrigger=function(e){return e&&!isNaN(e)?(p=Math.min(Math.max(0,e),1),D):p},D.onStepEnter=function(e){return"function"==typeof e?i.stepEnter=e:console.error("scrollama error: onStepEnter requires a function"),D},D.onStepExit=function(e){return"function"==typeof e?i.stepExit=e:console.error("scrollama error: onStepExit requires a function"),D},D.onStepProgress=function(e){return"function"==typeof e?i.stepProgress=e:console.error("scrollama error: onStepProgress requires a function"),D},D}});
/*!
* Stickyfill – `position: sticky` polyfill
* v. 2.0.2 | https://github.com/wilddeer/stickyfill
* v. 2.1.0 | https://github.com/wilddeer/stickyfill
* MIT License
*/
!function(a,b){"use strict";function c(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function d(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c])}function e(a){return parseFloat(a)||0}function f(a){for(var b=0;a;)b+=a.offsetTop,a=a.offsetParent;return b}function g(){function c(){a.pageXOffset!=k.left?(k.top=a.pageYOffset,k.left=a.pageXOffset,n.refreshAll()):a.pageYOffset!=k.top&&(k.top=a.pageYOffset,k.left=a.pageXOffset,l.forEach(function(a){return a._recalcPosition()}))}function d(){f=setInterval(function(){l.forEach(function(a){return a._fastCheck()})},500)}function e(){clearInterval(f)}c(),a.addEventListener("scroll",c),a.addEventListener("resize",n.refreshAll),a.addEventListener("orientationchange",n.refreshAll);var f=void 0,g=void 0,h=void 0;"hidden"in b?(g="hidden",h="visibilitychange"):"webkitHidden"in b&&(g="webkitHidden",h="webkitvisibilitychange"),h?(b[g]||d(),b.addEventListener(h,function(){b[g]?e():d()})):d()}var h=function(){function a(a,b){for(var c=0;c<b.length;c++){var d=b[c];d.enumerable=d.enumerable||!1,d.configurable=!0,"value"in d&&(d.writable=!0),Object.defineProperty(a,d.key,d)}}return function(b,c,d){return c&&a(b.prototype,c),d&&a(b,d),b}}(),i=!1;a.getComputedStyle?!function(){var a=b.createElement("div");["","-webkit-","-moz-","-ms-"].some(function(b){try{a.style.position=b+"sticky"}catch(a){}return""!=a.style.position})&&(i=!0)}():i=!0;var j="undefined"!=typeof ShadowRoot,k={top:null,left:null},l=[],m=function(){function g(a){if(c(this,g),!(a instanceof HTMLElement))throw new Error("First argument must be HTMLElement");if(l.some(function(b){return b._node===a}))throw new Error("Stickyfill is already applied to this node");this._node=a,this._stickyMode=null,this._active=!1,l.push(this),this.refresh()}return h(g,[{key:"refresh",value:function(){if(!i&&!this._removed){this._active&&this._deactivate();var c=this._node,g=getComputedStyle(c);if(!isNaN(parseFloat(g.top))&&"table-cell"!=g.display&&"none"!=g.display){this._active=!0;var h=c.parentNode,k=j&&h instanceof ShadowRoot?h.host:h,l=c.getBoundingClientRect(),m=k.getBoundingClientRect(),n=getComputedStyle(k);this._parent={node:k,styles:{position:k.style.position},offsetHeight:k.offsetHeight},this._offsetToWindow={left:l.left,right:b.documentElement.clientWidth-l.right},this._offsetToParent={top:l.top-m.top-e(n.borderTopWidth),left:l.left-m.left-e(n.borderLeftWidth),right:-l.right+m.right-e(n.borderRightWidth)},this._styles={position:c.style.position,top:c.style.top,bottom:c.style.bottom,left:c.style.left,right:c.style.right,width:c.style.width,marginTop:c.style.marginTop,marginLeft:c.style.marginLeft,marginRight:c.style.marginRight};var o=e(g.top);this._limits={start:l.top+a.pageYOffset-o,end:m.top+a.pageYOffset+k.offsetHeight-e(n.borderBottomWidth)-c.offsetHeight-o-e(g.marginBottom)};var p=n.position;"absolute"!=p&&"relative"!=p&&(k.style.position="relative");var q=this._clone={};q.node=b.createElement("div"),d(q.node.style,{width:l.right-l.left+"px",height:l.bottom-l.top+"px",marginTop:g.marginTop,marginBottom:g.marginBottom,marginLeft:g.marginLeft,marginRight:g.marginRight,cssFloat:g.cssFloat,padding:0,border:0,borderSpacing:0,fontSize:"1em",position:"static"}),h.insertBefore(q.node,c),q.docOffsetTop=f(q.node),this._recalcPosition()}}}},{key:"_recalcPosition",value:function(){if(this._active&&!this._removed){var a=k.top<=this._limits.start?"start":k.top>=this._limits.end?"end":"middle";if(this._stickyMode!=a){switch(a){case"start":d(this._node.style,{position:"absolute",left:this._offsetToParent.left+"px",right:this._offsetToParent.right+"px",top:this._offsetToParent.top+"px",bottom:"auto",width:"auto",marginLeft:0,marginRight:0,marginTop:0});break;case"middle":d(this._node.style,{position:"fixed",left:this._offsetToWindow.left+"px",right:this._offsetToWindow.right+"px",top:this._styles.top,bottom:"auto",width:"auto",marginLeft:0,marginRight:0,marginTop:0});break;case"end":d(this._node.style,{position:"absolute",left:this._offsetToParent.left+"px",right:this._offsetToParent.right+"px",top:"auto",bottom:0,width:"auto",marginLeft:0,marginRight:0})}this._stickyMode=a}}}},{key:"_fastCheck",value:function(){this._active&&!this._removed&&(Math.abs(f(this._clone.node)-this._clone.docOffsetTop)>1||Math.abs(this._parent.node.offsetHeight-this._parent.offsetHeight)>1)&&this.refresh()}},{key:"_deactivate",value:function(){var a=this;this._active&&!this._removed&&(this._clone.node.parentNode.removeChild(this._clone.node),delete this._clone,d(this._node.style,this._styles),delete this._styles,l.some(function(b){return b!==a&&b._parent&&b._parent.node===a._parent.node})||d(this._parent.node.style,this._parent.styles),delete this._parent,this._stickyMode=null,this._active=!1,delete this._offsetToWindow,delete this._offsetToParent,delete this._limits)}},{key:"remove",value:function(){var a=this;this._deactivate(),l.some(function(b,c){if(b._node===a._node)return l.splice(c,1),!0}),this._removed=!0}}]),g}(),n={stickies:l,Sticky:m,addOne:function(a){if(!(a instanceof HTMLElement)){if(!a.length||!a[0])return;a=a[0]}for(var b=0;b<l.length;b++)if(l[b]._node===a)return l[b];return new m(a)},add:function(a){if(a instanceof HTMLElement&&(a=[a]),a.length){for(var b=[],c=function(c){var d=a[c];return d instanceof HTMLElement?l.some(function(a){if(a._node===d)return b.push(a),!0})?"continue":void b.push(new m(d)):(b.push(void 0),"continue")},d=0;d<a.length;d++){c(d)}return b}},refreshAll:function(){l.forEach(function(a){return a.refresh()})},removeOne:function(a){if(!(a instanceof HTMLElement)){if(!a.length||!a[0])return;a=a[0]}l.some(function(b){if(b._node===a)return b.remove(),!0})},remove:function(a){if(a instanceof HTMLElement&&(a=[a]),a.length)for(var b=function(b){var c=a[b];l.some(function(a){if(a._node===c)return a.remove(),!0})},c=0;c<a.length;c++)b(c)},removeAll:function(){for(;l.length;)l[0].remove()}};i||g(),"undefined"!=typeof module&&module.exports?module.exports=n:a.Stickyfill=n}(window,document);
!function(a,b){"use strict";function c(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function d(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c])}function e(a){return parseFloat(a)||0}function f(a){for(var b=0;a;)b+=a.offsetTop,a=a.offsetParent;return b}function g(){function c(){a.pageXOffset!=m.left?(m.top=a.pageYOffset,m.left=a.pageXOffset,p.refreshAll()):a.pageYOffset!=m.top&&(m.top=a.pageYOffset,m.left=a.pageXOffset,n.forEach(function(a){return a._recalcPosition()}))}function d(){f=setInterval(function(){n.forEach(function(a){return a._fastCheck()})},500)}function e(){clearInterval(f)}if(!k){k=!0,c(),a.addEventListener("scroll",c),a.addEventListener("resize",p.refreshAll),a.addEventListener("orientationchange",p.refreshAll);var f=void 0,g=void 0,h=void 0;"hidden"in b?(g="hidden",h="visibilitychange"):"webkitHidden"in b&&(g="webkitHidden",h="webkitvisibilitychange"),h?(b[g]||d(),b.addEventListener(h,function(){b[g]?e():d()})):d()}}var h=function(){function a(a,b){for(var c=0;c<b.length;c++){var d=b[c];d.enumerable=d.enumerable||!1,d.configurable=!0,"value"in d&&(d.writable=!0),Object.defineProperty(a,d.key,d)}}return function(b,c,d){return c&&a(b.prototype,c),d&&a(b,d),b}}(),i=!1,j="undefined"!=typeof a;j&&a.getComputedStyle?!function(){var a=b.createElement("div");["","-webkit-","-moz-","-ms-"].some(function(b){try{a.style.position=b+"sticky"}catch(a){}return""!=a.style.position})&&(i=!0)}():i=!0;var k=!1,l="undefined"!=typeof ShadowRoot,m={top:null,left:null},n=[],o=function(){function g(a){if(c(this,g),!(a instanceof HTMLElement))throw new Error("First argument must be HTMLElement");if(n.some(function(b){return b._node===a}))throw new Error("Stickyfill is already applied to this node");this._node=a,this._stickyMode=null,this._active=!1,n.push(this),this.refresh()}return h(g,[{key:"refresh",value:function(){if(!i&&!this._removed){this._active&&this._deactivate();var c=this._node,g=getComputedStyle(c),h={position:g.position,top:g.top,display:g.display,marginTop:g.marginTop,marginBottom:g.marginBottom,marginLeft:g.marginLeft,marginRight:g.marginRight,cssFloat:g.cssFloat};if(!isNaN(parseFloat(h.top))&&"table-cell"!=h.display&&"none"!=h.display){this._active=!0;var j=c.style.position;"sticky"!=g.position&&"-webkit-sticky"!=g.position||(c.style.position="static");var k=c.parentNode,m=l&&k instanceof ShadowRoot?k.host:k,n=c.getBoundingClientRect(),o=m.getBoundingClientRect(),p=getComputedStyle(m);this._parent={node:m,styles:{position:m.style.position},offsetHeight:m.offsetHeight},this._offsetToWindow={left:n.left,right:b.documentElement.clientWidth-n.right},this._offsetToParent={top:n.top-o.top-e(p.borderTopWidth),left:n.left-o.left-e(p.borderLeftWidth),right:-n.right+o.right-e(p.borderRightWidth)},this._styles={position:j,top:c.style.top,bottom:c.style.bottom,left:c.style.left,right:c.style.right,width:c.style.width,marginTop:c.style.marginTop,marginLeft:c.style.marginLeft,marginRight:c.style.marginRight};var q=e(h.top);this._limits={start:n.top+a.pageYOffset-q,end:o.top+a.pageYOffset+m.offsetHeight-e(p.borderBottomWidth)-c.offsetHeight-q-e(h.marginBottom)};var r=p.position;"absolute"!=r&&"relative"!=r&&(m.style.position="relative"),this._recalcPosition();var s=this._clone={};s.node=b.createElement("div"),d(s.node.style,{width:n.right-n.left+"px",height:n.bottom-n.top+"px",marginTop:h.marginTop,marginBottom:h.marginBottom,marginLeft:h.marginLeft,marginRight:h.marginRight,cssFloat:h.cssFloat,padding:0,border:0,borderSpacing:0,fontSize:"1em",position:"static"}),k.insertBefore(s.node,c),s.docOffsetTop=f(s.node)}}}},{key:"_recalcPosition",value:function(){if(this._active&&!this._removed){var a=m.top<=this._limits.start?"start":m.top>=this._limits.end?"end":"middle";if(this._stickyMode!=a){switch(a){case"start":d(this._node.style,{position:"absolute",left:this._offsetToParent.left+"px",right:this._offsetToParent.right+"px",top:this._offsetToParent.top+"px",bottom:"auto",width:"auto",marginLeft:0,marginRight:0,marginTop:0});break;case"middle":d(this._node.style,{position:"fixed",left:this._offsetToWindow.left+"px",right:this._offsetToWindow.right+"px",top:this._styles.top,bottom:"auto",width:"auto",marginLeft:0,marginRight:0,marginTop:0});break;case"end":d(this._node.style,{position:"absolute",left:this._offsetToParent.left+"px",right:this._offsetToParent.right+"px",top:"auto",bottom:0,width:"auto",marginLeft:0,marginRight:0})}this._stickyMode=a}}}},{key:"_fastCheck",value:function(){this._active&&!this._removed&&(Math.abs(f(this._clone.node)-this._clone.docOffsetTop)>1||Math.abs(this._parent.node.offsetHeight-this._parent.offsetHeight)>1)&&this.refresh()}},{key:"_deactivate",value:function(){var a=this;this._active&&!this._removed&&(this._clone.node.parentNode.removeChild(this._clone.node),delete this._clone,d(this._node.style,this._styles),delete this._styles,n.some(function(b){return b!==a&&b._parent&&b._parent.node===a._parent.node})||d(this._parent.node.style,this._parent.styles),delete this._parent,this._stickyMode=null,this._active=!1,delete this._offsetToWindow,delete this._offsetToParent,delete this._limits)}},{key:"remove",value:function(){var a=this;this._deactivate(),n.some(function(b,c){if(b._node===a._node)return n.splice(c,1),!0}),this._removed=!0}}]),g}(),p={stickies:n,Sticky:o,forceSticky:function(){i=!1,g(),this.refreshAll()},addOne:function(a){if(!(a instanceof HTMLElement)){if(!a.length||!a[0])return;a=a[0]}for(var b=0;b<n.length;b++)if(n[b]._node===a)return n[b];return new o(a)},add:function(a){if(a instanceof HTMLElement&&(a=[a]),a.length){for(var b=[],c=function(c){var d=a[c];return d instanceof HTMLElement?n.some(function(a){if(a._node===d)return b.push(a),!0})?"continue":void b.push(new o(d)):(b.push(void 0),"continue")},d=0;d<a.length;d++){c(d)}return b}},refreshAll:function(){n.forEach(function(a){return a.refresh()})},removeOne:function(a){if(!(a instanceof HTMLElement)){if(!a.length||!a[0])return;a=a[0]}n.some(function(b){if(b._node===a)return b.remove(),!0})},remove:function(a){if(a instanceof HTMLElement&&(a=[a]),a.length)for(var b=function(b){var c=a[b];n.some(function(a){if(a._node===c)return a.remove(),!0})},c=0;c<a.length;c++)b(c)},removeAll:function(){for(;n.length;)n[0].remove()}};i||g(),"undefined"!=typeof module&&module.exports?module.exports=p:j&&(a.Stickyfill=p)}(window,document);
{
"name": "scrollama",
"version": "1.4.4",
"version": "2.0.0",
"description": "Lightweight scrollytelling library using IntersectionObserver",

@@ -5,0 +5,0 @@ "main": "build/scrollama.js",

@@ -10,9 +10,7 @@ ###### scrollama.js

**Notes: As of version 1.4.0, you must manually add the IntersectionObserver polyfill for cross-browser support. See [installation](https://github.com/russellgoldenberg/scrollama#installation) for details. Although it remains in the API (for now), it is recommended to use the CSS property `position: sticky;` instead of `.onContainerEnter` and `.onContainerExit`. [Full blog post here](https://pudding.cool/process/scrollytelling-sticky/).**
#### Important Changes
As seen on [The Pudding](https://pudding.cool/):
- **Version 2.0.0+**: `.onContainerEnter` and `.onContainerExit` have been deprecated in favor of CSS property `position: sticky;`. [How to use position sticky.](https://pudding.cool/process/scrollytelling-sticky/)
- **Version 1.4.0+**: you must manually add the IntersectionObserver polyfill for cross-browser support. See [installation](https://github.com/russellgoldenberg/scrollama#installation) for details.
- [What is a Superteam in the NBA?](https://pudding.cool/2017/10/superteams/)
- [What City is the Microbrew Capital of the US?](https://pudding.cool/2017/04/beer/)
[Jump to examples.](https://github.com/russellgoldenberg/scrollama#examples)

@@ -26,7 +24,3 @@

[IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
to handle element position detection. It offers an opinionated (but popular)
scrollytelling pattern to reduce more involved DOM calculations. The sticky
graphic pattern (enter-stick-exit) can be seen below. Check out my
[blog post](https://pudding.cool/process/introducing-scrollama) for a deeper
introduction.
to handle element position detection.

@@ -44,13 +38,6 @@ [![scrollytelling pattern](https://thumbs.gfycat.com/FearfulHotArabianoryx-size_restricted.gif)](https://pudding.cool/process/how-to-implement-scrollytelling)

incremental step progress callback
- [Sticky Graphic v1a (CSS, position sticky)](https://russellgoldenberg.github.io/scrollama/sticky-css) -
using CSS vertically center chart, and position sticky (+ polyfill) for
sticking.
- [Sticky Graphic v1b (JS, position sticky)](https://russellgoldenberg.github.io/scrollama/sticky-js) -
using JS vertically center chart, and position sticky (+ polyfill) for
sticking. Added bonus ability to start chart at top of steps then vertically.
- [Sticky Graphic v2a (CSS, position fixed)](https://russellgoldenberg.github.io/scrollama/fixed-css) -
using CSS vertically center chart, and position fixed and absolute for
sticking.
- [Sticky Graphic v2b (JS, position fixed)](https://russellgoldenberg.github.io/scrollama/fixed-js) -
using read position fixed and absolute for sticking.
- [Sticky Graphic (Side by Side)](https://russellgoldenberg.github.io/scrollama/sticky-side) -
using CSS `position: sticky;` to create a fixed graphic to the side of the text.
- [Sticky Graphic (Overlay)](https://russellgoldenberg.github.io/scrollama/sticky-overlay) -
using CSS `position: sticky;` to create a fixed graphic with fullscreen graphic with text overlayed.

@@ -64,4 +51,4 @@ ### Installation

```html
<script src='https://unpkg.com/intersection-observer@0.5.0/intersection-observer.js'></script>
<script src='https://unpkg.com/scrollama'></script>
<script src="https://unpkg.com/intersection-observer@0.5.1/intersection-observer.js"></script>
<script src="https://unpkg.com/scrollama"></script>
```

@@ -72,3 +59,3 @@

```sh
npm install scrollama intersection-observer
npm install scrollama intersection-observer --save
```

@@ -98,5 +85,5 @@

<!--you don't need the "data-step" attr, but can be useful for storing instructions for JS -->
<div class='step' data-step='a'></div>
<div class='step' data-step='b'></div>
<div class='step' data-step='c'></div>
<div class="step" data-step="a"></div>
<div class="step" data-step="b"></div>
<div class="step" data-step="c"></div>
```

@@ -117,42 +104,2 @@

#### Sticky Graphic
**Update:** I recommend using the CSS property `position:sticky;`. You can simply use the triggers like above, and let the CSS handle everything else. [Full blog post here](https://pudding.cool/process/scrollytelling-sticky/).
To implement the sticky graphic scrollytelling pattern, you need the following
three elements (container, graphic, steps). The structure should look like:
```html
<!-- container = ".scroll" -->
<div class='scroll'>
<!-- graphic = ".scroll__graphic" -->
<div class='scroll__graphic'>
<!--graphic / chart code here-->
</div>
<div class='scroll__text'>
<!-- steps = ".step" -->
<div class='step' data-step='a'></div>
<div class='step' data-step='b'></div>
<div class='step' data-step='c'></div>
</div>
</div>
```
```js
// instantiate the scrollama
const scroller = scrollama();
// setup the instance, pass callback functions
scroller
.setup({
step: '.scroll__text .step', // required
container: '.scroll', // required (for sticky)
graphic: '.scroll__graphic' // required (for sticky)
})
.onStepEnter(handleStepEnter)
.onStepExit(handleStepExit)
.onContainerEnter(handleContainerEnter)
.onContainerExit(handleContainerExit);
```
### API

@@ -166,6 +113,2 @@

**required**
- `container` (string): Selector (or element) for the element that contains everything for
the scroller. **optional**
- `graphic` (string): Selector (or element) for the graphic element that will become fixed.
**optional**
- `offset` (number, 0 - 1): How far from the top of the viewport to trigger a

@@ -175,5 +118,5 @@ step. **(default: 0.5)**

not. **(default: false)**
- `threshold` (number, 1+): The granularity of the progress interval, in pixels (smaller = more granular updates). **(default: 4)**
- `order` (boolean): Whether to preserve step triggering order if they fire out of sync (eg. ensure step 2 enters after 1 exits). **(default: true)**
- `once` (boolean): Only trigger the step to enter once then remove listener. **default: false**
- `threshold` (number, 1+): The granularity of the progress interval in pixels (smaller = more granular). **(default: 4)**
- `order` (boolean): Fire previous step triggers if they were jumped. **(default: true)**
- `once` (boolean): Only trigger the step to enter once then remove listener. **(default: false)**
- `debug` (boolean): Whether to show visual debugging tools or not. **(default:

@@ -220,20 +163,2 @@ false)**

#### scrollama.onContainerEnter(callback)
Callback that fires when the top of container becomes flush with viewport _or_
the graphic becomes fully in view coming from the bottom of the container.
The argument of the callback is an object: `{ direction: string }`
`direction`: 'up' or 'down'
#### scrollama.onContainerExit(callback)
Callback that fires when the top of container goes below viewport _or_ the
graphic becomes not full in view leaving the bottom of the container.
The argument of the callback is an object: `{ direction: string }`
`direction`: 'up' or 'down'
#### scrollama.offsetTrigger([number])

@@ -240,0 +165,0 @@

@@ -1,43 +0,50 @@

import { select, selectAll } from './dom';
import { selectAll } from './dom';
import * as bug from './debug';
function scrollama() {
const ZERO_MOE = 1; // zero with some rounding margin of error
const margin = {};
const callback = {};
const OBSERVER_NAMES = [
'stepAbove',
'stepBelow',
'stepProgress',
'viewportAbove',
'viewportBelow'
];
const cb = {
stepEnter: () => {},
stepExit: () => {},
stepProgress: () => {}
};
const io = {};
let containerEl = null;
let graphicEl = null;
let stepEl = null;
let id = null;
let stepEl = [];
let stepOffsetHeight = [];
let stepOffsetTop = [];
let stepStates = [];
let id = null;
let offsetVal = 0;
let offsetMargin = 0;
let vh = 0;
let ph = 0;
let stepOffsetHeight = null;
let stepOffsetTop = null;
let bboxGraphic = null;
let viewH = 0;
let pageH = 0;
let previousYOffset = 0;
let progressThreshold = 0;
let isReady = false;
let isEnabled = false;
let debugMode = false;
let isDebug = false;
let progressMode = false;
let progressThreshold = 0;
let preserveOrder = false;
let triggerOnce = false;
let stepStates = null;
let containerState = null;
let previousYOffset = -1;
let direction = null;
let direction = 'down';
const exclude = [];
// HELPERS
function generateId() {
/*** HELPERS ***/
function generateInstanceID() {
const a = 'abcdefghijklmnopqrstuv';
const l = a.length;
const t = new Date().getTime();
const t = Date.now();
const r = [0, 0, 0].map(d => a[Math.floor(Math.random() * l)]).join('');

@@ -87,18 +94,19 @@ return `${r}${t}`;

function disconnectObserver(name) {
if (io[name]) io[name].forEach(d => d.disconnect());
}
function handleResize() {
vh = window.innerHeight;
ph = getPageHeight();
viewH = window.innerHeight;
pageH = getPageHeight();
bboxGraphic = graphicEl ? graphicEl.getBoundingClientRect() : null;
offsetMargin = offsetVal * viewH;
offsetMargin = offsetVal * vh;
if (isReady) {
stepOffsetHeight = stepEl.map(el => el.offsetHeight);
stepOffsetTop = stepEl.map(getOffsetTop);
if (isEnabled) updateIO();
}
stepOffsetHeight = stepEl ? stepEl.map(el => el.offsetHeight) : [];
stepOffsetTop = stepEl ? stepEl.map(getOffsetTop) : [];
if (isEnabled && isReady) updateIO();
if (debugMode)
bug.update({ id, stepOffsetHeight, offsetMargin, offsetVal });
if (isDebug) bug.update({ id, stepOffsetHeight, offsetMargin, offsetVal });
}

@@ -110,12 +118,6 @@

isEnabled = true;
} else if (!enable) {
if (io.top) io.top.disconnect();
if (io.bottom) io.bottom.disconnect();
if (io.stepAbove) io.stepAbove.forEach(d => d.disconnect());
if (io.stepBelow) io.stepBelow.forEach(d => d.disconnect());
if (io.stepProgress) io.stepProgress.forEach(d => d.disconnect());
if (io.viewportAbove) io.viewportAbove.forEach(d => d.disconnect());
if (io.viewportBelow) io.viewportBelow.forEach(d => d.disconnect());
isEnabled = false;
return true;
}
OBSERVER_NAMES.forEach(disconnectObserver);
isEnabled = false;
}

@@ -133,3 +135,12 @@

// NOTIFY CALLBACKS
/*** NOTIFY CALLBACKS ***/
function notifyStepProgress(element, progress) {
const index = getIndex(element);
if (progress !== undefined) stepStates[index].progress = progress;
const resp = { element, index, progress: stepStates[index].progress };
if (stepStates[index].state === 'enter') cb.stepProgress(resp);
}
function notifyOthers(index, location) {

@@ -140,7 +151,10 @@ if (location === 'above') {

const ss = stepStates[i];
if (ss.state === 'enter') notifyStepExit(stepEl[i], 'down');
if (ss.direction === 'up') {
if (ss.state !== 'enter' && ss.direction !== 'down') {
notifyStepEnter(stepEl[i], 'down', false);
notifyStepExit(stepEl[i], 'down');
}
} else if (ss.state === 'enter') notifyStepExit(stepEl[i], 'down');
// else if (ss.direction === 'up') {
// notifyStepEnter(stepEl[i], 'down', false);
// notifyStepExit(stepEl[i], 'down');
// }
}

@@ -168,3 +182,2 @@ } else if (location === 'below') {

stepStates[index].state = 'enter';
if (preserveOrder && check && direction === 'down')

@@ -176,16 +189,9 @@ notifyOthers(index, 'above');

if (
callback.stepEnter &&
typeof callback.stepEnter === 'function' &&
!exclude[index]
) {
callback.stepEnter(resp, stepStates);
if (debugMode) bug.notifyStep({ id, index, state: 'enter' });
if (cb.stepEnter && !exclude[index]) {
cb.stepEnter(resp, stepStates);
if (isDebug) bug.notifyStep({ id, index, state: 'enter' });
if (triggerOnce) exclude[index] = true;
}
if (progressMode) {
if (direction === 'down') notifyStepProgress(element, 0);
else notifyStepProgress(element, 1);
}
if (progressMode) notifyStepProgress(element);
}

@@ -197,2 +203,9 @@

if (progressMode) {
if (direction === 'down' && stepStates[index].progress < 1)
notifyStepProgress(element, 1);
else if (direction === 'up' && stepStates[index].progress > 0)
notifyStepProgress(element, 0);
}
// store most recent trigger

@@ -202,98 +215,73 @@ stepStates[index].direction = direction;

if (progressMode) {
if (direction === 'down') notifyStepProgress(element, 1);
else notifyStepProgress(element, 0);
}
if (callback.stepExit && typeof callback.stepExit === 'function') {
callback.stepExit(resp, stepStates);
if (debugMode) bug.notifyStep({ id, index, state: 'exit' });
}
cb.stepExit(resp, stepStates);
if (isDebug) bug.notifyStep({ id, index, state: 'exit' });
}
function notifyStepProgress(element, progress) {
const index = getIndex(element);
const resp = { element, index, progress };
if (callback.stepProgress && typeof callback.stepProgress === 'function')
callback.stepProgress(resp);
}
/*** OBSERVER - INTERSECT HANDLING ***/
// this is good for entering while scrolling down + leaving while scrolling up
function intersectStepAbove([entry]) {
updateDirection();
const { isIntersecting, boundingClientRect, target } = entry;
function notifyContainerEnter() {
const resp = { direction };
containerState.direction = direction;
containerState.state = 'enter';
// bottom = bottom edge of element from top of viewport
// bottomAdjusted = bottom edge of element from trigger
const { top, bottom } = boundingClientRect;
const topAdjusted = top - offsetMargin;
const bottomAdjusted = bottom - offsetMargin;
const index = getIndex(target);
const ss = stepStates[index];
// entering above is only when topAdjusted is negative
// and bottomAdjusted is positive
if (
callback.containerEnter &&
typeof callback.containerEnter === 'function'
isIntersecting &&
topAdjusted <= 0 &&
bottomAdjusted >= 0 &&
direction === 'down' &&
ss.state !== 'enter'
)
callback.containerEnter(resp);
}
notifyStepEnter(target, direction);
function notifyContainerExit() {
const resp = { direction };
containerState.direction = direction;
containerState.state = 'exit';
if (callback.containerExit && typeof callback.containerExit === 'function')
callback.containerExit(resp);
// exiting from above is when topAdjusted is positive and not intersecting
if (
!isIntersecting &&
topAdjusted > 0 &&
direction === 'up' &&
ss.state === 'enter'
)
notifyStepExit(target, direction);
}
// OBSERVER - INTERSECT HANDLING
// if TOP edge of step crosses threshold,
// bottom must be > 0 which means it is on "screen" (shifted by offset)
function intersectStepAbove(entries) {
// this is good for entering while scrolling up + leaving while scrolling down
function intersectStepBelow([entry]) {
updateDirection();
entries.forEach(entry => {
const { isIntersecting, boundingClientRect, target } = entry;
const { isIntersecting, boundingClientRect, target } = entry;
// bottom is how far bottom edge of el is from top of viewport
const { bottom, height } = boundingClientRect;
const bottomAdjusted = bottom - offsetMargin;
const index = getIndex(target);
const ss = stepStates[index];
// bottom = bottom edge of element from top of viewport
// bottomAdjusted = bottom edge of element from trigger
const { top, bottom } = boundingClientRect;
const topAdjusted = top - offsetMargin;
const bottomAdjusted = bottom - offsetMargin;
const index = getIndex(target);
const ss = stepStates[index];
if (bottomAdjusted >= -ZERO_MOE) {
if (isIntersecting && direction === 'down' && ss.state !== 'enter')
notifyStepEnter(target, direction);
else if (!isIntersecting && direction === 'up' && ss.state === 'enter')
notifyStepExit(target, direction);
else if (
!isIntersecting &&
bottomAdjusted >= height &&
direction === 'down' &&
ss.state === 'enter'
) {
notifyStepExit(target, direction);
}
}
});
}
// entering below is only when bottomAdjusted is positive
// and topAdjusted is positive
if (
isIntersecting &&
topAdjusted <= 0 &&
bottomAdjusted >= 0 &&
direction === 'up' &&
ss.state !== 'enter'
)
notifyStepEnter(target, direction);
function intersectStepBelow(entries) {
updateDirection();
entries.forEach(entry => {
const { isIntersecting, boundingClientRect, target } = entry;
const { bottom, height } = boundingClientRect;
const bottomAdjusted = bottom - offsetMargin;
const index = getIndex(target);
const ss = stepStates[index];
if (
bottomAdjusted >= -ZERO_MOE &&
bottomAdjusted < height &&
isIntersecting &&
direction === 'up' &&
ss.state !== 'enter'
) {
notifyStepEnter(target, direction);
} else if (
bottomAdjusted <= ZERO_MOE &&
!isIntersecting &&
direction === 'down' &&
ss.state === 'enter'
) {
notifyStepExit(target, direction);
}
});
// exiting from above is when bottomAdjusted is negative and not intersecting
if (
!isIntersecting &&
bottomAdjusted < 0 &&
direction === 'down' &&
ss.state === 'enter'
)
notifyStepExit(target, direction);
}

@@ -306,117 +294,60 @@

*/
function intersectViewportAbove(entries) {
function intersectViewportAbove([entry]) {
updateDirection();
entries.forEach(entry => {
const { isIntersecting, target } = entry;
const index = getIndex(target);
const ss = stepStates[index];
if (
isIntersecting &&
direction === 'down' &&
ss.state !== 'enter' &&
ss.direction !== 'down'
) {
notifyStepEnter(target, 'down');
notifyStepExit(target, 'down');
}
});
}
const { isIntersecting, target } = entry;
const index = getIndex(target);
const ss = stepStates[index];
function intersectViewportBelow(entries) {
updateDirection();
entries.forEach(entry => {
const { isIntersecting, target } = entry;
const index = getIndex(target);
const ss = stepStates[index];
if (
isIntersecting &&
direction === 'up' &&
ss.state !== 'enter' &&
ss.direction !== 'up'
) {
notifyStepEnter(target, 'up');
notifyStepExit(target, 'up');
}
});
if (
isIntersecting &&
direction === 'down' &&
ss.direction !== 'down' &&
ss.state !== 'enter'
) {
notifyStepEnter(target, 'down');
notifyStepExit(target, 'down');
}
}
function intersectStepProgress(entries) {
function intersectViewportBelow([entry]) {
updateDirection();
entries.forEach(
({ isIntersecting, intersectionRatio, boundingClientRect, target }) => {
const { bottom } = boundingClientRect;
const bottomAdjusted = bottom - offsetMargin;
if (isIntersecting && bottomAdjusted >= -ZERO_MOE) {
notifyStepProgress(target, +intersectionRatio.toFixed(3));
}
}
);
}
function intersectTop(entries) {
updateDirection();
const { isIntersecting, boundingClientRect } = entries[0];
const { top, bottom } = boundingClientRect;
if (bottom > -ZERO_MOE) {
if (isIntersecting) notifyContainerEnter(direction);
else if (containerState.state === 'enter') notifyContainerExit(direction);
const { isIntersecting, target } = entry;
const index = getIndex(target);
const ss = stepStates[index];
if (
isIntersecting &&
direction === 'up' &&
ss.direction === 'down' &&
ss.state !== 'enter'
) {
notifyStepEnter(target, 'up');
notifyStepExit(target, 'up');
}
}
function intersectBottom(entries) {
function intersectStepProgress([entry]) {
updateDirection();
const { isIntersecting, boundingClientRect } = entries[0];
const { top } = boundingClientRect;
if (top < ZERO_MOE) {
if (isIntersecting) notifyContainerEnter(direction);
else if (containerState.state === 'enter') notifyContainerExit(direction);
const {
isIntersecting,
intersectionRatio,
boundingClientRect,
target
} = entry;
const { bottom } = boundingClientRect;
const bottomAdjusted = bottom - offsetMargin;
if (isIntersecting && bottomAdjusted >= 0) {
notifyStepProgress(target, +intersectionRatio.toFixed(3));
}
}
// OBSERVER - CREATION
function updateTopIO() {
if (io.top) io.top.unobserve(containerEl);
const options = {
root: null,
rootMargin: `${vh}px 0px -${vh}px 0px`,
threshold: 0
};
io.top = new IntersectionObserver(intersectTop, options);
io.top.observe(containerEl);
}
function updateBottomIO() {
if (io.bottom) io.bottom.unobserve(containerEl);
const options = {
root: null,
rootMargin: `-${bboxGraphic.height}px 0px ${bboxGraphic.height}px 0px`,
threshold: 0
};
io.bottom = new IntersectionObserver(intersectBottom, options);
io.bottom.observe(containerEl);
}
// top edge
function updateStepAboveIO() {
if (io.stepAbove) io.stepAbove.forEach(d => d.disconnect());
io.stepAbove = stepEl.map((el, i) => {
const marginTop = stepOffsetHeight[i];
const marginBottom = -vh + offsetMargin;
/*** OBSERVER - CREATION ***/
// jump into viewport
function updateViewportAboveIO() {
io.viewportAbove = stepEl.map((el, i) => {
const marginTop = pageH - stepOffsetTop[i];
const marginBottom = offsetMargin - viewH - stepOffsetHeight[i];
const rootMargin = `${marginTop}px 0px ${marginBottom}px 0px`;
const options = {
root: null,
rootMargin,
threshold: 0
};
const obs = new IntersectionObserver(intersectStepAbove, options);
const options = { rootMargin };
// console.log(options);
const obs = new IntersectionObserver(intersectViewportAbove, options);
obs.observe(el);

@@ -427,18 +358,10 @@ return obs;

// bottom edge
function updateStepBelowIO() {
if (io.stepBelow) io.stepBelow.forEach(d => d.disconnect());
io.stepBelow = stepEl.map((el, i) => {
const marginTop = -offsetMargin;
const marginBottom = ph - vh + stepOffsetHeight[i] + offsetMargin;
function updateViewportBelowIO() {
io.viewportBelow = stepEl.map((el, i) => {
const marginTop = -offsetMargin - stepOffsetHeight[i];
const marginBottom = offsetMargin - viewH + stepOffsetHeight[i] + pageH;
const rootMargin = `${marginTop}px 0px ${marginBottom}px 0px`;
const options = {
root: null,
rootMargin,
threshold: 0
};
const obs = new IntersectionObserver(intersectStepBelow, options);
const options = { rootMargin };
// console.log(options);
const obs = new IntersectionObserver(intersectViewportBelow, options);
obs.observe(el);

@@ -449,16 +372,11 @@ return obs;

// jump into viewport
function updateViewportAboveIO() {
if (io.viewportAbove) io.viewportAbove.forEach(d => d.disconnect());
io.viewportAbove = stepEl.map((el, i) => {
const marginTop = stepOffsetTop[i];
const marginBottom = -(vh - offsetMargin + stepOffsetHeight[i]);
// look above for intersection
function updateStepAboveIO() {
io.stepAbove = stepEl.map((el, i) => {
const marginTop = -offsetMargin + stepOffsetHeight[i];
const marginBottom = offsetMargin - viewH;
const rootMargin = `${marginTop}px 0px ${marginBottom}px 0px`;
const options = {
root: null,
rootMargin,
threshold: 0
};
const obs = new IntersectionObserver(intersectViewportAbove, options);
const options = { rootMargin };
// console.log(options);
const obs = new IntersectionObserver(intersectStepAbove, options);
obs.observe(el);

@@ -469,16 +387,11 @@ return obs;

function updateViewportBelowIO() {
if (io.viewportBelow) io.viewportBelow.forEach(d => d.disconnect());
io.viewportBelow = stepEl.map((el, i) => {
const marginTop = -(offsetMargin + stepOffsetHeight[i]);
const marginBottom =
ph - stepOffsetTop[i] - stepOffsetHeight[i] - offsetMargin;
// look below for intersection
function updateStepBelowIO() {
io.stepAbove = stepEl.map((el, i) => {
const marginTop = -offsetMargin;
const marginBottom = offsetMargin - viewH + stepOffsetHeight[i];
const rootMargin = `${marginTop}px 0px ${marginBottom}px 0px`;
const options = {
root: null,
rootMargin,
threshold: 0
};
const obs = new IntersectionObserver(intersectViewportBelow, options);
const options = { rootMargin };
// console.log(options);
const obs = new IntersectionObserver(intersectStepBelow, options);
obs.observe(el);

@@ -491,16 +404,9 @@ return obs;

function updateStepProgressIO() {
if (io.stepProgress) io.stepProgress.forEach(d => d.disconnect());
io.stepProgress = stepEl.map((el, i) => {
const marginTop = stepOffsetHeight[i] - offsetMargin;
const marginBottom = -vh + offsetMargin;
const marginBottom = -viewH + offsetMargin;
const rootMargin = `${marginTop}px 0px ${marginBottom}px 0px`;
const threshold = createThreshold(stepOffsetHeight[i]);
const options = {
root: null,
rootMargin,
threshold
};
const options = { rootMargin, threshold };
// console.log(options);
const obs = new IntersectionObserver(intersectStepProgress, options);

@@ -513,2 +419,4 @@ obs.observe(el);

function updateIO() {
OBSERVER_NAMES.forEach(disconnectObserver);
updateViewportAboveIO();

@@ -520,10 +428,5 @@ updateViewportBelowIO();

if (progressMode) updateStepProgressIO();
if (containerEl && graphicEl) {
updateTopIO();
updateBottomIO();
}
}
// SETUP FUNCTIONS
/*** SETUP FUNCTIONS ***/

@@ -537,10 +440,9 @@ function indexSteps() {

direction: null,
state: null
state: null,
progress: 0
}));
containerState = { direction: null, state: null };
}
function addDebug() {
if (debugMode) bug.setup({ id, stepEl, offsetVal });
if (isDebug) bug.setup({ id, stepEl, offsetVal });
}

@@ -551,4 +453,2 @@

S.setup = ({
container,
graphic,
step,

@@ -562,9 +462,7 @@ offset = 0.5,

}) => {
id = generateId();
// elements
// create id unique to this scrollama instance
id = generateInstanceID();
stepEl = selectAll(step);
containerEl = container ? select(container) : null;
graphicEl = graphic ? select(graphic) : null;
// error if no step selected
if (!stepEl.length) {

@@ -576,3 +474,3 @@ console.error('scrollama error: no step elements');

// options
debugMode = debug;
isDebug = debug;
progressMode = progress;

@@ -592,3 +490,3 @@ preserveOrder = order;

handleResize();
handleEnable(true);
S.enable();
return S;

@@ -614,3 +512,3 @@ };

handleEnable(false);
Object.keys(callback).forEach(c => (callback[c] = null));
Object.keys(cb).forEach(c => (cb[c] = null));
Object.keys(io).forEach(i => (io[i] = null));

@@ -627,27 +525,20 @@ };

S.onStepEnter = cb => {
callback.stepEnter = cb;
S.onStepEnter = f => {
if (typeof f === 'function') cb.stepEnter = f;
else console.error('scrollama error: onStepEnter requires a function');
return S;
};
S.onStepExit = cb => {
callback.stepExit = cb;
S.onStepExit = f => {
if (typeof f === 'function') cb.stepExit = f;
else console.error('scrollama error: onStepExit requires a function');
return S;
};
S.onStepProgress = cb => {
callback.stepProgress = cb;
S.onStepProgress = f => {
if (typeof f === 'function') cb.stepProgress = f;
else console.error('scrollama error: onStepProgress requires a function');
return S;
};
S.onContainerEnter = cb => {
callback.containerEnter = cb;
return S;
};
S.onContainerExit = cb => {
callback.containerExit = cb;
return S;
};
return S;

@@ -654,0 +545,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc