fullpage.js
Version:
Create beautiful fullscreen snap scrolling websites
1,701 lines (1,438 loc) • 197 kB
JavaScript
/*!
* fullPage 4.0.37
* https://github.com/alvarotrigo/fullPage.js
*
* @license GPLv3 for open source use only
* or Fullpage Commercial License for commercial use
* http://alvarotrigo.com/fullPage/pricing/
*
* Copyright (C) 2018 http://alvarotrigo.com/fullPage - A project by Alvaro Trigo
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.fullpage = factory());
})(this, (function () { 'use strict';
// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function value(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0; // 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
} // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1]; // 5. Let k be 0.
var k = 0; // 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
} // e. Increase k by 1.
k++;
} // 7. Return undefined.
return undefined;
}
});
}
// Production steps of ECMA-262, Edition 6, 22.1.2.1
if (!Array.from) {
Array.from = function () {
var toStr = Object.prototype.toString;
var isCallable = function isCallable(fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
};
var toInteger = function toInteger(value) {
var number = Number(value);
if (isNaN(number)) {
return 0;
}
if (number === 0 || !isFinite(number)) {
return number;
}
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function toLength(value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
}; // The length property of the from method is 1.
return function from(arrayLike
/*, mapFn, thisArg */
) {
// 1. Let C be the this value.
var C = this; // 2. Let items be ToObject(arrayLike).
var items = Object(arrayLike); // 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError('Array.from requires an array-like object - not null or undefined');
} // 4. If mapfn is undefined, then let mapping be false.
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
var T;
if (typeof mapFn !== 'undefined') {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
} // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 2) {
T = arguments[2];
}
} // 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength(items.length); // 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method
// of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable(C) ? Object(new C(len)) : new Array(len); // 16. Let k be 0.
var k = 0; // 17. Repeat, while k < len… (also steps a - h)
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
} // 18. Let putStatus be Put(A, "length", len, true).
A.length = len; // 20. Return A.
return A;
};
}();
}
var win = window;
var doc = document;
var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/) || navigator.userAgent.includes("Mac") && "ontouchend" in document; // iPad on iOS 13 detection
var isMacDevice = /(Mac|iPhone|iPod|iPad)/i.test(win.navigator.userAgent); // @ts-ignore
var isTouch = 'ontouchstart' in win || navigator.msMaxTouchPoints > 0 || navigator.maxTouchPoints;
var isIE11 = !!window.MSInputMethodContext && !!document.documentMode; // taken from https://github.com/udacity/ud891/blob/gh-pages/lesson2-focus/07-modals-and-keyboard-traps/solution/modal.js
var focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"], summary:not([disabled]), [contenteditable]'; // cache common elements
var FP = {
test: {},
shared: {}
};
var extensions = ['parallax', 'scrollOverflowReset', 'dragAndMove', 'offsetSections', 'fadingEffect', 'responsiveSlides', 'continuousHorizontal', 'interlockedSlides', 'scrollHorizontally', 'resetSliders', 'cards', 'dropEffect', 'waterEffect'];
var isInsideIframe = function () {
var inIframe = window.self !== window.top;
return function () {
return inIframe;
};
}();
/**
* forEach polyfill for IE
* https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Browser_Compatibility
*/
if (win.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function (callback, thisArg) {
thisArg = thisArg || window;
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}
if (typeof Object.assign != 'function') {
// Must be writable: true, enumerable: false, configurable: true
Object.defineProperty(Object, 'assign', {
value: function assign(target, varArgs) {
if (target == null) {
// TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) {
// Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}
// https://stackoverflow.com/questions/51719553/padstart-not-working-in-ie11
// https://github.com/behnammodi/polyfill/blob/master/string.polyfill.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
if (!String.prototype.padStart) {
String.prototype.padStart = function padStart(targetLength, padString) {
targetLength = targetLength >> 0; //truncate if number or convert non-number to 0;
padString = String(typeof padString !== 'undefined' ? padString : ' ');
if (this.length > targetLength) {
return String(this);
} else {
targetLength = targetLength - this.length;
if (targetLength > padString.length) {
padString += Array.apply(null, Array(targetLength)).map(function () {
return padString;
}).join("");
}
return padString.slice(0, targetLength) + String(this);
}
};
}
//utils
/**
* Shows a message in the console of the given type.
*/
function showError(type, text) {
win.console && win.console[type] && win.console[type]('fullPage: ' + text);
}
function isVisible(el) {
var style = win.getComputedStyle(el);
return style.display !== 'none';
}
function getVisible(elements) {
return Array.from(elements).filter(function (e) {
return isVisible(e);
});
}
/**
* Equivalent of jQuery function $().
*/
function $(selector, context) {
context = arguments.length > 1 ? context : document;
return context ? context.querySelectorAll(selector) : null;
}
/**
* Extends a given Object properties and its childs.
*/
function deepExtend(out) {
out = out || {};
for (var i = 1, len = arguments.length; i < len; ++i) {
var obj = arguments[i];
if (!obj) {
continue;
}
for (var key in obj) {
if (!obj.hasOwnProperty(key) || key == '__proto__' || key == 'constructor') {
continue;
} // based on https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
out[key] = deepExtend(out[key], obj[key]);
continue;
}
out[key] = obj[key];
}
}
return out;
}
/**
* Checks if the passed element contains the passed class.
*/
function hasClass(el, className) {
if (el == null) {
return false;
}
return el.classList.contains(className);
}
/**
* Gets the window height. Crossbrowser.
*/
function getWindowHeight() {
return 'innerHeight' in win ? win.innerHeight : doc.documentElement.offsetHeight;
}
/**
* Gets the window width.
*/
function getWindowWidth() {
return win.innerWidth;
}
/**
* Set's the CSS properties for the passed item/s.
* @param {NodeList|HTMLElement|Object} items
* @param {Object} props css properties and values.
*/
function css(items, props) {
items = getList(items);
var key;
for (key in props) {
if (props.hasOwnProperty(key)) {
if (key !== null) {
for (var i = 0; i < items.length; i++) {
var item = items[i];
item.style[key] = props[key];
}
}
}
}
return items;
}
/**
* Gets the previous element to the passed element.
*/
function prev(item) {
return item.previousElementSibling;
}
/**
* Gets the next element to the passed element.
*/
function next(item) {
return item.nextElementSibling;
}
/**
* Gets the last element from the passed list of elements.
*/
function last(item) {
return item[item.length - 1];
}
/**
* Gets index from the passed element.
* @param {String} selector is optional.
*/
function index(item, selector) {
item = isArrayOrList(item) ? item[0] : item;
var children = selector != null ? $(selector, item.parentNode) : item.parentNode.childNodes;
var num = 0;
for (var i = 0; i < children.length; i++) {
if (children[i] == item) return num;
if (children[i].nodeType == 1) num++;
}
return -1;
}
/**
* Gets an iterable element for the passed element/s
*/
function getList(item) {
return !isArrayOrList(item) ? [item] : item;
}
/**
* Adds the display=none property for the passed element/s
*/
function hide(el) {
el = getList(el);
for (var i = 0; i < el.length; i++) {
el[i].style.display = 'none';
}
return el;
}
/**
* Adds the display=block property for the passed element/s
*/
function show(el) {
el = getList(el);
for (var i = 0; i < el.length; i++) {
el[i].style.display = 'block';
}
return el;
}
/**
* Checks if the passed element is an iterable element or not
*/
function isArrayOrList(el) {
return Object.prototype.toString.call(el) === '[object Array]' || Object.prototype.toString.call(el) === '[object NodeList]';
}
/**
* Adds the passed class to the passed element/s
*/
function addClass(el, className) {
el = getList(el);
for (var i = 0; i < el.length; i++) {
var item = el[i];
item.classList.add(className);
}
return el;
}
/**
* Removes the passed class to the passed element/s
* @param {String} `className` can be multiple classnames separated by whitespace
*/
function removeClass(el, className) {
el = getList(el);
var classNames = className.split(' ');
for (var a = 0; a < classNames.length; a++) {
className = classNames[a];
for (var i = 0; i < el.length; i++) {
var item = el[i];
item.classList.remove(className);
}
}
return el;
}
/**
* Appends the given element ot the given parent.
*/
function appendTo(el, parent) {
parent.appendChild(el);
}
/**
Usage:
var wrapper = document.createElement('div');
wrapper.className = 'fp-slides';
wrap($('.slide'), wrapper);
https://jsfiddle.net/qwzc7oy3/15/ (vanilla)
https://jsfiddle.net/oya6ndka/1/ (jquery equivalent)
*/
function wrap(toWrap, wrapper, isWrapAll) {
var newParent;
wrapper = wrapper || doc.createElement('div');
for (var i = 0; i < toWrap.length; i++) {
var item = toWrap[i];
if (isWrapAll && !i || !isWrapAll) {
newParent = wrapper.cloneNode(true);
item.parentNode.insertBefore(newParent, item);
}
newParent.appendChild(item);
}
return toWrap;
}
/**
Usage:
var wrapper = document.createElement('div');
wrapper.className = 'fp-slides';
wrap($('.slide'), wrapper);
https://jsfiddle.net/qwzc7oy3/27/ (vanilla)
https://jsfiddle.net/oya6ndka/4/ (jquery equivalent)
*/
function wrapAll(toWrap, wrapper) {
wrap(toWrap, wrapper, true);
}
/**
* Usage:
* wrapInner(document.querySelector('#pepe'), '<div class="test">afdas</div>');
* wrapInner(document.querySelector('#pepe'), element);
*
* https://jsfiddle.net/zexxz0tw/6/
*
* https://stackoverflow.com/a/21817590/1081396
*/
function wrapInner(parent, wrapper) {
parent.appendChild(wrapper);
while (parent.firstChild !== wrapper) {
wrapper.appendChild(parent.firstChild);
}
}
/**
* Usage:
* unwrap(document.querySelector('#pepe'));
* unwrap(element);
*
* https://jsfiddle.net/szjt0hxq/1/
*
*/
function unwrap(wrapper) {
var wrapperContent = doc.createDocumentFragment();
while (wrapper.firstChild) {
wrapperContent.appendChild(wrapper.firstChild);
}
wrapper.parentNode.replaceChild(wrapperContent, wrapper);
}
/**
* http://stackoverflow.com/questions/22100853/dom-pure-javascript-solution-to-jquery-closest-implementation
* Returns the element or `false` if there's none
*/
function closest(el, selector) {
if (el && el.nodeType === 1) {
if (matches(el, selector)) {
return el;
}
return closest(el.parentNode, selector);
}
return null;
}
/**
* Places one element (rel) after another one or group of them (reference).
* @param {HTMLElement} reference
* @param {HTMLElement|NodeList|String|Array} el
* https://jsfiddle.net/9s97hhzv/1/
*/
function after(reference, el) {
insertBefore(reference, reference.nextSibling, el);
}
/**
* Places one element (rel) before another one or group of them (reference).
* @param {HTMLElement} reference
* @param {HTMLElement|NodeList|String|Array} el
* https://jsfiddle.net/9s97hhzv/1/
*/
function before(reference, el) {
insertBefore(reference, reference, el);
}
/**
* Based in https://stackoverflow.com/a/19316024/1081396
* and https://stackoverflow.com/a/4793630/1081396
*/
function insertBefore(reference, beforeElement, el) {
if (!isArrayOrList(el)) {
if (typeof el == 'string') {
el = createElementFromHTML(el);
}
el = [el];
}
for (var i = 0; i < el.length; i++) {
reference.parentNode.insertBefore(el[i], beforeElement);
}
} //http://stackoverflow.com/questions/3464876/javascript-get-window-x-y-position-for-scroll
function getScrollTop() {
var docElement = doc.documentElement;
return (win.pageYOffset || docElement.scrollTop) - (docElement.clientTop || 0);
}
/**
* Gets the siblings of the passed element
*/
function siblings(el) {
return Array.prototype.filter.call(el.parentNode.children, function (child) {
return child !== el;
});
}
function preventDefault(event) {
event.preventDefault();
}
function getAttr(el, attr) {
return el.getAttribute(attr);
}
function docAddEvent(event, callback, options) {
doc.addEventListener(event, callback, options === 'undefined' ? null : options);
}
function windowAddEvent(event, callback, options) {
win.addEventListener(event, callback, options === 'undefined' ? null : options);
}
function docRemoveEvent(event, callback, options) {
doc.removeEventListener(event, callback, options === 'undefined' ? null : options);
}
function windowRemoveEvent(event, callback, options) {
win.removeEventListener(event, callback, options === 'undefined' ? null : options);
}
/**
* Determines whether the passed item is of function type.
*/
function isFunction(item) {
if (typeof item === 'function') {
return true;
}
var type = Object.prototype.toString.call(item);
return type === '[object Function]' || type === '[object GeneratorFunction]';
}
/**
* Trigger custom events
*/
function trigger(el, eventName, data) {
var event;
data = typeof data === 'undefined' ? {} : data; // Native
if (typeof win.CustomEvent === "function") {
event = new CustomEvent(eventName, {
detail: data
});
} else {
event = doc.createEvent('CustomEvent');
event.initCustomEvent(eventName, true, true, data);
}
el.dispatchEvent(event);
}
/**
* Polyfill of .matches()
*/
function matches(el, selector) {
return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector);
}
/**
* Toggles the visibility of the passed element el.
*/
function toggle(el, value) {
if (typeof value === "boolean") {
for (var i = 0; i < el.length; i++) {
el[i].style.display = value ? 'block' : 'none';
}
} //we don't use it in other way, so no else :)
return el;
}
/**
* Creates a HTMLElement from the passed HTML string.
* https://stackoverflow.com/a/494348/1081396
*/
function createElementFromHTML(htmlString) {
var div = doc.createElement('div');
div.innerHTML = htmlString.trim(); // Change this to div.childNodes to support multiple top-level nodes
return div.firstChild;
}
/**
* Removes the passed item/s from the DOM.
*/
function remove(items) {
items = getList(items);
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item && item.parentElement) {
item.parentNode.removeChild(item);
}
}
} //https://jsfiddle.net/w1rktecz/
function untilAll(item, selector, fn) {
var sibling = item[fn];
var siblings = [];
while (sibling) {
if (matches(sibling, selector) || selector == null) {
siblings.push(sibling);
}
sibling = sibling[fn];
}
return siblings;
}
/**
* Gets all next elements matching the passed selector.
*/
function nextAll(item, selector) {
return untilAll(item, selector, 'nextElementSibling');
}
/**
* Gets all previous elements matching the passed selector.
*/
function prevAll(item, selector) {
return untilAll(item, selector, 'previousElementSibling');
}
/**
* Converts an object to an array.
*/
function toArray(objectData) {
return Object.keys(objectData).map(function (key) {
return objectData[key];
});
}
function getLast(items) {
return items[items.length - 1];
}
/**
* Gets the average of the last `number` elements of the given array.
*/
function getAverage(elements, number) {
var sum = 0; //taking `number` elements from the end to make the average, if there are not enought, 1
var lastElements = elements.slice(Math.max(elements.length - number, 1));
for (var i = 0; i < lastElements.length; i++) {
sum = sum + lastElements[i];
}
return Math.ceil(sum / number);
}
/**
* Sets the value for the given attribute from the `data-` attribute with the same suffix
* ie: data-srcset ==> srcset | data-src ==> src
*/
function setSrc(element, attribute) {
element.setAttribute(attribute, getAttr(element, 'data-' + attribute));
element.removeAttribute('data-' + attribute);
}
function getParentsUntil(item, topParentSelector) {
var parents = [item];
do {
item = item.parentNode;
parents.push(item);
} while (!matches(item, topParentSelector));
return parents;
}
function isInsideInput() {
var activeElement = doc.activeElement;
return matches(activeElement, 'textarea') || matches(activeElement, 'input') || matches(activeElement, 'select') || getAttr(activeElement, 'contentEditable') == "true" || getAttr(activeElement, 'contentEditable') == '';
} //utils are public, so we can use it wherever we want
// @ts-ignore
window["fp_utils"] = {
"$": $,
"deepExtend": deepExtend,
"hasClass": hasClass,
"getWindowHeight": getWindowHeight,
"css": css,
"prev": prev,
"next": next,
"last": last,
"index": index,
"getList": getList,
"hide": hide,
"show": show,
"isArrayOrList": isArrayOrList,
"addClass": addClass,
"removeClass": removeClass,
"appendTo": appendTo,
"wrap": wrap,
"wrapAll": wrapAll,
"unwrap": unwrap,
"closest": closest,
"after": after,
"before": before,
"insertBefore": insertBefore,
"getScrollTop": getScrollTop,
"siblings": siblings,
"preventDefault": preventDefault,
"isFunction": isFunction,
"trigger": trigger,
"matches": matches,
"toggle": toggle,
"createElementFromHTML": createElementFromHTML,
"remove": remove,
// "filter": filter,
"untilAll": untilAll,
"nextAll": nextAll,
"prevAll": prevAll,
"showError": showError
};
var utils = /*#__PURE__*/Object.freeze({
__proto__: null,
showError: showError,
isVisible: isVisible,
getVisible: getVisible,
$: $,
deepExtend: deepExtend,
hasClass: hasClass,
getWindowHeight: getWindowHeight,
getWindowWidth: getWindowWidth,
css: css,
prev: prev,
next: next,
last: last,
index: index,
getList: getList,
hide: hide,
show: show,
isArrayOrList: isArrayOrList,
addClass: addClass,
removeClass: removeClass,
appendTo: appendTo,
wrap: wrap,
wrapAll: wrapAll,
wrapInner: wrapInner,
unwrap: unwrap,
closest: closest,
after: after,
before: before,
insertBefore: insertBefore,
getScrollTop: getScrollTop,
siblings: siblings,
preventDefault: preventDefault,
getAttr: getAttr,
docAddEvent: docAddEvent,
windowAddEvent: windowAddEvent,
docRemoveEvent: docRemoveEvent,
windowRemoveEvent: windowRemoveEvent,
isFunction: isFunction,
trigger: trigger,
matches: matches,
toggle: toggle,
createElementFromHTML: createElementFromHTML,
remove: remove,
untilAll: untilAll,
nextAll: nextAll,
prevAll: prevAll,
toArray: toArray,
getLast: getLast,
getAverage: getAverage,
setSrc: setSrc,
getParentsUntil: getParentsUntil,
isInsideInput: isInsideInput
});
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
var EventEmitter = {
events: {},
on: function on(event, listener) {
var _this = this;
if (_typeof(this.events[event]) !== 'object') {
this.events[event] = [];
}
this.events[event].push(listener);
return function () {
return _this.removeListener(event, listener);
};
},
removeListener: function removeListener(event, listener) {
if (_typeof(this.events[event]) === 'object') {
var idx = this.events[event].indexOf(listener);
if (idx > -1) {
this.events[event].splice(idx, 1);
}
}
},
emit: function emit(event) {
var _this2 = this;
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
if (_typeof(this.events[event]) === 'object') {
this.events[event].forEach(function (listener) {
return listener.apply(_this2, args);
});
}
},
once: function once(event, listener) {
var _this3 = this;
var remove = this.on(event, function () {
remove();
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
listener.apply(_this3, args);
});
}
};
var defaultState = {
numSections: 0,
numSlides: 0,
slides: [],
sections: [],
activeSection: null,
scrollTrigger: null,
isBeyondFullpage: false,
aboutToScrollToFullPage: false,
slideMoving: false,
isResizing: false,
isScrolling: false,
lastScrolledDestiny: undefined,
lastScrolledSlide: undefined,
activeAnimation: false,
canScroll: true,
touchDirection: 'none',
wheelDirection: 'none',
isGrabbing: false,
isUsingWheel: false,
isWindowFocused: true,
previousDestTop: 0,
windowsHeight: getWindowHeight(),
isDoingContinousVertical: false,
timeouts: {},
scrollY: 0,
scrollX: 0,
isFullpageInitDone: false
};
var state = Object.assign({}, defaultState); // @ts-ignore
win.state = state;
function setState(props) {
Object.assign(state, props);
}
function getState() {
return state;
}
function getActivePanel() {
return state.activeSection && state.activeSection.activeSlide ? state.activeSection.activeSlide : state.activeSection;
}
function resetState() {
setState(defaultState);
}
var events = {
onAfterRenderNoAnchor: 'onAfterRenderNoAnchor',
onClickOrTouch: 'onClickOrTouch',
moveSlideLeft: 'moveSlideLeft',
moveSlideRight: 'moveSlideRight',
onInitialise: 'onInitialise',
beforeInit: 'beforeInit',
bindEvents: 'bindEvents',
onDestroy: 'onDestroy',
onDestroyAll: 'onDestroyAll',
contentChanged: 'contentChanged',
onScrollOverflowScrolled: 'onScrollOverflowScrolled',
onScrollPageAndSlide: 'onScrollPageAndSlide',
onKeyDown: 'onKeyDown',
onMenuClick: 'onMenuClick',
scrollPage: 'scrollPage',
landscapeScroll: 'landscapeScroll',
scrollBeyondFullpage: 'scrollBeyondFullpage',
onPerformMovement: 'onPerformMovement',
onSlideLeave: 'onSlideLeave',
onLeave: 'onLeave',
afterSectionLoads: 'afterSectionLoads',
afterSlideLoads: 'afterSlideLoads'
};
EventEmitter.on(events.bindEvents, bindEvents$c);
function bindEvents$c() {
//Scrolls to the section when clicking the navigation bullet
//simulating the jQuery .on('click') event using delegation
['click', 'touchstart'].forEach(function (eventName) {
docAddEvent(eventName, delegatedEvents);
});
windowAddEvent('focus', focusHandler);
internalEvents();
}
function internalEvents() {
EventEmitter.on(events.onDestroy, onDestroy$9);
}
function delegatedEvents(e) {
EventEmitter.emit(events.onClickOrTouch, {
e: e,
target: e.target
});
}
function onDestroy$9() {
['click', 'touchstart'].forEach(function (eventName) {
docRemoveEvent(eventName, delegatedEvents);
});
} // changing isWindowFocused to true on focus event
function focusHandler() {
setState({
isWindowFocused: true
});
}
// keeping central set of classnames and selectors
var WRAPPER = 'fullpage-wrapper';
var WRAPPER_SEL = '.' + WRAPPER; // slimscroll
var SCROLLABLE = 'fp-scrollable';
var RESPONSIVE = 'fp-responsive';
var NO_TRANSITION = 'fp-notransition';
var DESTROYED = 'fp-destroyed';
var ENABLED = 'fp-enabled';
var VIEWING_PREFIX = 'fp-viewing';
var ACTIVE = 'active';
var ACTIVE_SEL = '.' + ACTIVE;
var COMPLETELY = 'fp-completely';
var COMPLETELY_SEL = '.' + COMPLETELY;
var LOADED = 'fp-loaded';
var SECTION_DEFAULT_SEL = '.section';
var SECTION = 'fp-section';
var SECTION_SEL = '.' + SECTION;
var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL;
var TABLE_CELL = 'fp-tableCell';
var TABLE_CELL_SEL = '.' + TABLE_CELL;
var AUTO_HEIGHT = 'fp-auto-height';
var AUTO_HEIGHT_SEL = '.' + AUTO_HEIGHT;
var AUTO_HEIGHT_RESPONSIVE = 'fp-auto-height-responsive';
var AUTO_HEIGHT_RESPONSIVE_SEL = '.' + AUTO_HEIGHT_RESPONSIVE;
var NORMAL_SCROLL = 'fp-normal-scroll';
var SECTION_NAV = 'fp-nav';
var SECTION_NAV_SEL = '#' + SECTION_NAV;
var SECTION_NAV_TOOLTIP = 'fp-tooltip';
var SECTION_NAV_TOOLTIP_SEL = '.' + SECTION_NAV_TOOLTIP;
var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; // slide
var SLIDE_DEFAULT_SEL = '.slide';
var SLIDE = 'fp-slide';
var SLIDE_SEL = '.' + SLIDE;
var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL;
var SLIDES_WRAPPER = 'fp-slides';
var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER;
var SLIDES_CONTAINER = 'fp-slidesContainer';
var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER;
var TABLE = 'fp-table';
var OVERFLOW = 'fp-overflow';
var OVERFLOW_SEL = '.' + OVERFLOW;
var IS_OVERFLOW = 'fp-is-overflow'; // slide nav
var SLIDES_NAV = 'fp-slidesNav';
var SLIDES_NAV_SEL = '.' + SLIDES_NAV;
var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a';
var SLIDES_STYLED_ARROW = 'fp-arrow';
var SLIDES_ARROW = 'fp-controlArrow';
var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW;
var SLIDES_PREV = 'fp-prev';
var SLIDES_PREV_SEL = '.' + SLIDES_PREV;
var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL;
var SLIDES_NEXT = 'fp-next';
var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT;
var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; // Watermark
var WATERMARK = 'fp-watermark';
var WATERMARK_SEL = '.' + WATERMARK;
var defaultOptions = {
//navigation
menu: false,
anchors: [],
lockAnchors: false,
navigation: false,
navigationPosition: 'right',
navigationTooltips: [],
showActiveTooltip: false,
slidesNavigation: false,
slidesNavPosition: 'bottom',
scrollBar: false,
hybrid: false,
licenseKey: '',
credits: {
"enabled": true,
"label": 'Made with fullPage.js',
"position": 'right'
},
//scrolling
css3: true,
scrollingSpeed: 700,
autoScrolling: true,
fitToSection: true,
fitToSectionDelay: 600,
easing: 'easeInOutCubic',
easingcss3: 'ease',
loopBottom: false,
loopTop: false,
loopHorizontal: true,
continuousVertical: false,
continuousHorizontal: false,
scrollHorizontally: false,
interlockedSlides: false,
dragAndMove: false,
offsetSections: false,
resetSliders: false,
fadingEffect: false,
normalScrollElements: null,
scrollOverflow: true,
scrollOverflowReset: false,
skipIntermediateItems: false,
touchSensitivity: 5,
touchWrapper: null,
bigSectionsDestination: null,
adjustOnNavChange: true,
//Accessibility
keyboardScrolling: true,
animateAnchor: true,
recordHistory: true,
allowCorrectDirection: false,
//design
scrollOverflowMacStyle: true,
controlArrows: true,
controlArrowsHTML: ['<div class="' + SLIDES_STYLED_ARROW + '"></div>', '<div class="' + SLIDES_STYLED_ARROW + '"></div>'],
controlArrowColor: '#fff',
verticalCentered: true,
sectionsColor: [],
paddingTop: 0,
paddingBottom: 0,
fixedElements: null,
responsive: 0,
//backwards compabitility with responsiveWiddth
responsiveWidth: 0,
responsiveHeight: 0,
responsiveSlides: false,
parallax: false,
parallaxOptions: {
type: 'reveal',
percentage: 62,
property: 'translate'
},
cards: false,
cardsOptions: {
perspective: 100,
fadeContent: true,
fadeBackground: true
},
//Custom selectors
sectionSelector: SECTION_DEFAULT_SEL,
slideSelector: SLIDE_DEFAULT_SEL,
//events
afterLoad: null,
beforeLeave: null,
onLeave: null,
afterRender: null,
afterResize: null,
afterReBuild: null,
afterSlideLoad: null,
onSlideLeave: null,
afterResponsive: null,
onScrollOverflow: null,
lazyLoading: true,
lazyLoadThreshold: 0,
observer: true,
scrollBeyondFullpage: true
};
var container = null;
var g_initialAnchorsInDom = false;
var originals = deepExtend({}, defaultOptions); //deep copy
var g_options = null;
function getInitialAnchorsInDom() {
return g_initialAnchorsInDom;
}
function setContainer(value) {
container = value;
}
function getContainer(value) {
return container;
}
function getOptions() {
return g_options || defaultOptions;
}
function setOptions(options) {
g_options = deepExtend({}, defaultOptions, options);
originals = Object.assign({}, g_options);
}
function getOriginals() {
return originals;
}
function setOption(name, value) {
defaultOptions[name] = value;
}
/*
* Sets the state for a variable with multiple states (original, and temporal)
* Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`.
* This function is used to keep track of both states, the original and the temporal one.
* If type is not 'internal', then we assume the user is globally changing the variable.
*/
function setVariableState(variable, value, type) {
g_options[variable] = value;
if (type !== 'internal') {
originals[variable] = value;
}
}
/**
* Setting options from DOM elements if they are not provided.
*/
function setOptionsFromDOM() {
//no anchors option? Checking for them in the DOM attributes
if (!getOptions().anchors.length) {
var anchorsAttribute = '[data-anchor]';
var anchors = $(getOptions().sectionSelector.split(',').join(anchorsAttribute + ',') + anchorsAttribute, container);
if (anchors.length && anchors.length === $(getOptions().sectionSelector, container).length) {
g_initialAnchorsInDom = true;
anchors.forEach(function (item) {
getOptions().anchors.push(getAttr(item, 'data-anchor').toString());
});
}
} //no tooltips option? Checking for them in the DOM attributes
if (!getOptions().navigationTooltips.length) {
var tooltipsAttribute = '[data-tooltip]';
var tooltips = $(getOptions().sectionSelector.split(',').join(tooltipsAttribute + ',') + tooltipsAttribute, container);
if (tooltips.length) {
tooltips.forEach(function (item) {
getOptions().navigationTooltips.push(getAttr(item, 'data-tooltip').toString());
});
}
}
}
var plainItem = function plainItem(panel) {
this.anchor = panel.anchor;
this.item = panel.item;
this.index = panel.index();
this.isLast = this.index === panel.item.parentElement.querySelectorAll(panel.selector).length - 1;
this.isFirst = !this.index;
this.isActive = panel.isActive;
};
/**
* Item. Slide or Section objects share the same properties.
*/
var Item = function Item(el, selector) {
this.parent = this.parent || null;
this.selector = selector;
this.anchor = getAttr(el, 'data-anchor') || getOptions().anchors[index(el, getOptions().sectionSelector)];
this.item = el;
this.isVisible = isVisible(el);
this.isActive = hasClass(el, ACTIVE);
this.hasScroll = hasClass(el, OVERFLOW) || $(OVERFLOW_SEL, el)[0] != null;
this.isSection = selector === getOptions().sectionSelector;
this.container = closest(el, SLIDES_CONTAINER_SEL) || closest(el, WRAPPER_SEL);
this.index = function () {
return this.siblings().indexOf(this);
};
};
Item.prototype.siblings = function () {
if (this.isSection) {
if (this.isVisible) {
return state.sections;
} else {
return state.sectionsIncludingHidden;
}
}
return this.parent ? this.parent.slides : 0;
};
Item.prototype.prev = function () {
var siblings = this.siblings();
var currentIndex = this.isSection ? siblings.indexOf(this) : this.parent.slides.indexOf(this);
var prevIndex = currentIndex - 1;
if (prevIndex >= 0) {
return siblings[prevIndex];
}
return null;
};
Item.prototype.next = function () {
var siblings = this.siblings();
var currentIndex = this.isSection ? siblings.indexOf(this) : this.parent.slides.indexOf(this);
var nextIndex = currentIndex + 1;
if (nextIndex < siblings.length) {
return siblings[nextIndex];
}
return null;
};
Item.prototype["prevPanel"] = function () {
return this.prev() || (this.parent ? this.parent.prev() : null);
};
Item.prototype["nextPanel"] = function () {
return this.next() || (this.parent ? this.parent.next() : null);
};
Item.prototype.getSiblings = function () {
if (this.isSection) {
return state.sections;
}
return state.panels;
};
function getNodes(panels) {
return panels.map(function (panel) {
return panel.item;
});
}
function getPanelByElement(panels, el) {
return panels.find(function (panel) {
return panel.item === el;
});
}
var Section = function Section(el) {
plainItem.call(this, el);
};
var Slide = function Slide(el) {
plainItem.call(this, el);
};
/**
* Gets the active slide (or section) for the given section
*/
function getSlideOrSection(destiny) {
var slide = $(SLIDE_ACTIVE_SEL, destiny);
if (slide.length) {
destiny = slide[0];
}
return destiny;
}
function getSlideOrSectionPanel(panel) {
if (!panel) {
return null;
}
return panel.activeSlide ? panel.activeSlide : panel;
}
function isFullPageAbove() {
return getContainer().getBoundingClientRect().bottom >= 0;
}
/**
* Gets the scrolling settings depending on the plugin autoScrolling option
*/
function getScrollSettings(top) {
var options = getOptions();
var position;
var element; //top property animation
if (options.autoScrolling && !options.scrollBar) {
position = -top;
element = $(WRAPPER_SEL)[0];
} //window real scrolling
else {
position = top;
element = window;
}
return {
options: position,
element: element
};
}
/**
* Scrolls the page / slider the given number of pixels.
* It will do it one or another way dependiong on the library's config.
*/
function setScrolling(element, val) {
if (!getOptions().autoScrolling || getOptions().scrollBar || element.self != window && hasClass(element, SLIDES_WRAPPER)) {
//scrolling horizontally through the slides?
if (element.self != window && hasClass(element, SLIDES_WRAPPER)) {
element.scrollLeft = val;
} //vertical scroll
else {
element.scrollTo(0, val);
}
} else {
element.style.top = val + 'px';
}
}
/**
* Adds transition animations for the given element
*/
function addAnimation(element) {
var transition = 'transform ' + getOptions().scrollingSpeed + 'ms ' + getOptions().easingcss3;
removeClass(element, NO_TRANSITION);
return css(element, {
'-webkit-transition': transition,
'transition': transition
});
}
/**
* Retuns `up` or `down` depending on the scrolling movement to reach its destination
* from the current section.
*/
function getYmovement(activeSection, destiny) {
var fromIndex = activeSection.index();
var toIndex = index(destiny, SECTION_SEL);
if (fromIndex == toIndex) {
return 'none';
}
if (fromIndex > toIndex) {
return 'up';
}
return 'down';
}
/**
* Remove transition animations for the given element
*/
function removeAnimation(element) {
return addClass(element, NO_TRANSITION);
}
/**
* Returns the cross-browser transform string.
*/
function getTransforms(translate3d) {
return {
'-webkit-transform': translate3d,
'-moz-transform': translate3d,
'-ms-transform': translate3d,
'transform': translate3d
};
}
var silentScrollId;
/**
* Adds a css3 transform property to the container class with or without animation depending on the animated param.
*/
function transformContainer(translate3d, animated) {
if (animated) {
addAnimation(getContainer());
} else {
removeAnimation(getContainer());
}
clearTimeout(silentScrollId);
css(getContainer(), getTransforms(translate3d));
FP.test.translate3d = translate3d; //syncronously removing the class after the animation has been applied.
silentScrollId = setTimeout(function () {
removeClass(getContainer(), NO_TRANSITION);
}, 10);
}
/**
* Scrolls silently (with no animation) the page to the given Y position.
*/
function silentScroll(top) {
// The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
// that's why we round it to 0.
var roundedTop = Math.round(top);
if (getOptions().css3 && getOptions().autoScrolling && !getOptions().scrollBar) {
var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)';
transformContainer(translate3d, false);
} else if (getOptions().autoScrolling && !getOptions().scrollBar) {
css(getContainer(), {
'top': -roundedTop + 'px'
});
FP.test.top = -roundedTop + 'px';
} else {
var scrollSettings = getScrollSettings(roundedTop);
setScrolling(scrollSettings.element, scrollSettings.options);
}
}
FP.setScrollingSpeed = setScrollingSpeed;
/**
* Defines the scrolling speed
*/
function setScrollingSpeed(value, type) {
setVariableState('scrollingSpeed', value, type);
}
var $body = null;
var $html = null;
var $htmlBody = null; // caching common elements
function setCache() {
$body = $('body')[0];
$html = $('html')[0];
$htmlBody = $('html, body');
}
//@ts-check
var _g_animateScroll;
/**
* Simulates the animated scrollTop of jQuery. Used when css3:false or scrollBar:true or autoScrolling:false
* http://stackoverflow.com/a/16136789/1081396
*/
function scrollTo(element, to, duration, callback) {
var start = getScrolledPosition(element);
var change = to - start;
var isCallbackFired = false;
var startTime;
var wasAnimationActive = state.activeAnimation;
setState({
activeAnimation: true
}); // Cancelling any possible previous animations (io: clicking on nav dots very fast)
if (_g_animateScroll) {
window.cancelAnimationFrame(_g_animateScroll);
}
_g_animateScroll = function g_animateScroll(timestamp) {
if (!startTime) {
startTime = timestamp;
}
var currentTime = Math.floor(timestamp - startTime);
if (state.activeAnimation) {
//in order to stope it from other function whenever we want
var val = to;
if (duration) {
// @ts-ignore
val = win.fp_easings[getOptions().easing](currentTime, start, change, duration);
}
if (currentTime <= duration) {
setScrolling(element, val);
}
if (currentTime < duration) {
window.requestAnimationFrame(_g_animateScroll);
} else if (typeof callback !== 'undefined' && !isCallbackFired) {
setScrolling(element, to);
callback();
setState({
activeAnimation: false
});
isCallbackFired = true;
}
} else if (!isCallbackFired && !wasAnimationActive) {
callback();
setState({
activeAnimation: false
});
isCallbackFired = true;
}
};
window.requestAnimationFrame(_g_animateScroll);
}
/**
* Getting the position of the element to scroll when using jQuery animations
*/
function getScrolledPosition(element) {
var position; //is not the window element and is a slide?
if (element.self != win && hasClass(element, SLIDES_WRAPPER)) {
position = element.scrollLeft;
} else if (!getOptions().autoScrolling || getOptions().scrollBar) {
position = getScrollTop();
} else {
position = element.offsetTop;
} //gets the top property of the wrapper
return position;
}
/**
* Makes sure to only create a Panel object if the element exist
*/
function nullOrSection(el) {
if (el && !el.item) {
return new Section(new SectionPanel(el));
}
return el ? new Section(el) : null;
}
function nullOrSlide(el) {
return el ? new Slide(el) : null;
}
/**
* Dispatch events & callbacks
*/
function fireCallback(eventName, v) {
var eventData = getEventData(eventName, v);
trigger(getContainer(), eventName, eventData);
if (getOptions()[eventName].apply(eventData[Object.keys(eventData)[0]], toArray(eventData)) === false) {
return false;
}
return true;
}
/**
* Gets the event's data for the given event on the right format.
*/
function getEventData(eventName, v) {
//using functions to run only the necessary bits within the object
var paramsPerEvent = {
afterRender: function afterRender() {
return {
section: nullOrSection(getState().activeSection),
slide: nullOrSlide(getState().activeSection.activeSlide)
};
},
onLeave: function onLeave() {
return {
origin: nullOrSection(v.items.origin),
destination: nullOrSection(v.items.destination),
directio