@kddy/vue-scrollactive
Version:
Lightweight and simple to use vue component that highlights menu items as you scroll the page, also scrolling to target section when clicked.
1,122 lines (924 loc) • 232 kB
JavaScript
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./src/sandbox/sandbox.js");
/******/ })
/************************************************************************/
/******/ ({
/***/ "./node_modules/@babel/runtime/helpers/arrayLikeToArray.js":
/*!*****************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/arrayLikeToArray.js ***!
\*****************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) {
arr2[i] = arr[i];
}
return arr2;
}
module.exports = _arrayLikeToArray;
/***/ }),
/***/ "./node_modules/@babel/runtime/helpers/arrayWithoutHoles.js":
/*!******************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/arrayWithoutHoles.js ***!
\******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var arrayLikeToArray = __webpack_require__(/*! ./arrayLikeToArray */ "./node_modules/@babel/runtime/helpers/arrayLikeToArray.js");
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return arrayLikeToArray(arr);
}
module.exports = _arrayWithoutHoles;
/***/ }),
/***/ "./node_modules/@babel/runtime/helpers/asyncToGenerator.js":
/*!*****************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/asyncToGenerator.js ***!
\*****************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
module.exports = _asyncToGenerator;
/***/ }),
/***/ "./node_modules/@babel/runtime/helpers/classCallCheck.js":
/*!***************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/classCallCheck.js ***!
\***************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
module.exports = _classCallCheck;
/***/ }),
/***/ "./node_modules/@babel/runtime/helpers/createClass.js":
/*!************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/createClass.js ***!
\************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
module.exports = _createClass;
/***/ }),
/***/ "./node_modules/@babel/runtime/helpers/iterableToArray.js":
/*!****************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/iterableToArray.js ***!
\****************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
module.exports = _iterableToArray;
/***/ }),
/***/ "./node_modules/@babel/runtime/helpers/nonIterableSpread.js":
/*!******************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/nonIterableSpread.js ***!
\******************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
module.exports = _nonIterableSpread;
/***/ }),
/***/ "./node_modules/@babel/runtime/helpers/toConsumableArray.js":
/*!******************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/toConsumableArray.js ***!
\******************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var arrayWithoutHoles = __webpack_require__(/*! ./arrayWithoutHoles */ "./node_modules/@babel/runtime/helpers/arrayWithoutHoles.js");
var iterableToArray = __webpack_require__(/*! ./iterableToArray */ "./node_modules/@babel/runtime/helpers/iterableToArray.js");
var unsupportedIterableToArray = __webpack_require__(/*! ./unsupportedIterableToArray */ "./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js");
var nonIterableSpread = __webpack_require__(/*! ./nonIterableSpread */ "./node_modules/@babel/runtime/helpers/nonIterableSpread.js");
function _toConsumableArray(arr) {
return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();
}
module.exports = _toConsumableArray;
/***/ }),
/***/ "./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js":
/*!***************************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js ***!
\***************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var arrayLikeToArray = __webpack_require__(/*! ./arrayLikeToArray */ "./node_modules/@babel/runtime/helpers/arrayLikeToArray.js");
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);
}
module.exports = _unsupportedIterableToArray;
/***/ }),
/***/ "./node_modules/@babel/runtime/regenerator/index.js":
/*!**********************************************************!*\
!*** ./node_modules/@babel/runtime/regenerator/index.js ***!
\**********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(/*! regenerator-runtime */ "./node_modules/regenerator-runtime/runtime.js");
/***/ }),
/***/ "./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js?!./src/scrollactive.vue?vue&type=script&lang=js&":
/*!*****************************************************************************************************************************************!*\
!*** ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib??vue-loader-options!./src/scrollactive.vue?vue&type=script&lang=js& ***!
\*****************************************************************************************************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ "./node_modules/@babel/runtime/helpers/toConsumableArray.js");
/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/regenerator */ "./node_modules/@babel/runtime/regenerator/index.js");
/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/asyncToGenerator */ "./node_modules/@babel/runtime/helpers/asyncToGenerator.js");
/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var bezier_easing__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! bezier-easing */ "./node_modules/bezier-easing/src/index.js");
/* harmony import */ var bezier_easing__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(bezier_easing__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _ScrollContainer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ScrollContainer */ "./src/ScrollContainer.js");
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils */ "./src/utils/index.js");
/* harmony default export */ __webpack_exports__["default"] = ({
props: {
/**
* Active class that will be applied to the active item.
*/
activeClass: {
type: String,
"default": 'is-active'
},
/**
* Amount of space between top of screen and the section to highlight. (Usually your fixed
* header's height).
*/
offset: {
type: Number,
"default": 20
},
/**
* Amount of space between the top of the screen and the section to highlight when clicking a
* scrollactive item to scroll. It will use the value of the `offset` prop if none is provided
* here. Useful when you want to use the `offset` prop to make an item be active as soon as
* it shows on the screen but still scroll to the top of the section when clicking the item.
*/
scrollOffset: {
type: Number,
"default": null
},
/**
* The selector string of the scroll container element you'd like to use. It defaults to the
* window object (most common), but you might want to change in case you're using an element
* as container with overflow.
*/
scrollContainerSelector: {
type: String,
"default": ''
},
/**
* Enables/disables the scrolling when clicking in a menu item.
* Disable if you'd like to handle the scrolling by your own.
*/
clickToScroll: {
type: Boolean,
"default": true
},
/**
* The duration of the scroll animation when clicking to scroll is activated.
*/
duration: {
type: Number,
"default": 600
},
/**
* Defines if the plugin should track the section change when clicking an item to scroll to
* its section. If set to true, it will always keep track and change the active class to the
* current section while scrolling, if false, the active class will be immediately applied to
* the clicked menu item, ignoring the passed sections until the scrolling is over.
*/
alwaysTrack: {
type: Boolean,
"default": false
},
/**
* Your custom easing value for the click to scroll functionality.
* It must be a string with 4 values separated by commas in a cubic bezier format.
*/
bezierEasingValue: {
type: String,
"default": '.5,0,.35,1'
},
/**
* Decides if the URL should be modified with the section id when clicking a scrollactive
* item.
*/
modifyUrl: {
type: Boolean,
"default": true
},
/**
* If true the active class will only be applied when a section matches exactly one of the
* scrollactive items, meaning it will be highlighted when scrolling exactly inside the
* section. If false (default) it will always highlight the last item which was matched
* in a section, even if it is already outside that section (and not inside another that's
* being tracked).
*/
exact: {
type: Boolean,
"default": false
},
/**
* If true the active class will be applied to the first scrollactive-item before you scroll
* past it (even if you didn't reach it yet).
*/
highlightFirstItem: {
type: Boolean,
"default": false
},
/**
* Changes the scrollactive container component html tag.
*/
tag: {
type: String,
"default": 'nav'
},
/**
* If true the screen will scroll down to the element in the URL when the component is mounted.
*/
scrollOnStart: {
type: Boolean,
"default": true
}
},
data: function data() {
return {
observer: null,
items: [],
currentItem: null,
lastActiveItem: null,
scrollAnimationFrame: null,
bezierEasing: bezier_easing__WEBPACK_IMPORTED_MODULE_3___default.a
};
},
computed: {
/**
* Computes the bezier easing string value into an array.
*/
cubicBezierArray: function cubicBezierArray() {
return this.bezierEasingValue.split(',');
},
scrollContainer: function scrollContainer() {
return new _ScrollContainer__WEBPACK_IMPORTED_MODULE_4__["ScrollContainer"](this.scrollContainerSelector);
}
},
mounted: function mounted() {
this.resetOnDOMChange();
this.initScrollactiveItems();
this.removeActiveClass();
this.currentItem = this.getItemInsideWindow();
if (this.currentItem) this.currentItem.classList.add(this.activeClass);
if (this.scrollOnStart) this.scrollToHashElement();
this.scrollContainer.addScrollListener(this.onScroll);
},
updated: function updated() {
this.initScrollactiveItems();
},
beforeDestroy: function beforeDestroy() {
this.scrollContainer.removeScrollListener();
window.cancelAnimationFrame(this.scrollAnimationFrame);
},
methods: {
/**
* Makes sure the component is recalculated whenever the DOM tree changes inside of the
* scrollactive wrapper.
*/
resetOnDOMChange: function resetOnDOMChange() {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
if (!this.observer) {
this.observer = new MutationObserver(this.initScrollactiveItems); // Calls this.initScrollactiveItems() whenever the DOM tree is changed inside of the wrapper
this.observer.observe(this.$refs['scrollactive-nav-wrapper'], {
childList: true,
subtree: true
});
}
},
/**
* Sets the list of menu items, adding or removing the click listener depending on the
* clickToScroll prop.
*/
initScrollactiveItems: function initScrollactiveItems() {
var _this = this;
var elements = this.$el.querySelectorAll('.scrollactive-item');
var items = [];
Object(_utils__WEBPACK_IMPORTED_MODULE_5__["forEach"])(elements, function (menuElement) {
var section = document.querySelector(Object(_utils__WEBPACK_IMPORTED_MODULE_5__["getSectionSelector"])(menuElement));
if (!section) return;
items.push({
section: section,
menuElement: menuElement
});
});
this.items = items;
if (this.clickToScroll) {
Object(_utils__WEBPACK_IMPORTED_MODULE_5__["forEach"])(elements, function (element) {
return element.addEventListener('click', _this.onMenuItemClick);
});
} else {
Object(_utils__WEBPACK_IMPORTED_MODULE_5__["forEach"])(elements, function (element) {
return element.removeEventListener('click', _this.onMenuItemClick);
});
}
},
/**
* Will be called when scrolling event is triggered to handle the addition of the active class
* in the current section item and fire the change event.
*/
onScroll: function onScroll(event) {
this.currentItem = this.getItemInsideWindow();
var sectionHasChanged = this.currentItem !== this.lastActiveItem;
if (sectionHasChanged) {
this.removeActiveClass();
this.$emit('itemchanged', event, this.currentItem, this.lastActiveItem);
this.lastActiveItem = this.currentItem;
} // Check first because item might be null if not inside any section
if (this.currentItem) this.currentItem.classList.add(this.activeClass);
},
/**
* Gets the scrollactive item that corresponds to the current section inside the window
*/
getItemInsideWindow: function getItemInsideWindow() {
var _this2 = this;
var currentItem;
Object(_utils__WEBPACK_IMPORTED_MODULE_5__["forEach"])(this.items, function (_ref, index) {
var menuElement = _ref.menuElement,
section = _ref.section;
var isFirstItem = index === 0;
var distanceFromTop = _this2.scrollContainer.getDistanceFromTop();
var targetOffsetTop = _this2.getOffsetTop(section) - _this2.offset;
var isScreenPastSectionStart = distanceFromTop >= targetOffsetTop;
var isScreenBeforeSectionEnd = distanceFromTop < targetOffsetTop + section.offsetHeight;
var isScreenInsideSection = isScreenPastSectionStart && isScreenBeforeSectionEnd;
if (isFirstItem && _this2.highlightFirstItem) {
if (isScreenBeforeSectionEnd) currentItem = menuElement;
}
if (_this2.exact && isScreenInsideSection) currentItem = menuElement;
if (!_this2.exact && isScreenPastSectionStart) currentItem = menuElement;
});
return currentItem;
},
/**
* Handles the scrolling when clicking a menu item.
*/
onMenuItemClick: function onMenuItemClick(event) {
var _this3 = this;
return _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_2___default()( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_1___default.a.mark(function _callee() {
var menuItem, sectionSelector, section;
return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_1___default.a.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
event.preventDefault();
menuItem = event.target;
sectionSelector = Object(_utils__WEBPACK_IMPORTED_MODULE_5__["getSectionSelector"])(menuItem);
section = document.querySelector(sectionSelector);
if (section) {
_context.next = 7;
break;
}
console.warn("[vue-scrollactive] Element '".concat(sectionSelector, "' was not found. Make sure it is set in the DOM."));
return _context.abrupt("return");
case 7:
/**
* Temporarily removes the scroll listener and the request animation frame so the active
* class will only be applied to the clicked element, and not all elements while the window
* is scrolling.
*/
if (!_this3.alwaysTrack) {
_this3.scrollContainer.removeScrollListener();
window.cancelAnimationFrame(_this3.scrollAnimationFrame);
_this3.removeActiveClass();
menuItem.classList.add(_this3.activeClass);
}
_context.next = 10;
return _this3.scrollTo(section);
case 10:
if (!_this3.alwaysTrack) {
_this3.scrollContainer.addScrollListener(_this3.onScroll);
_this3.currentItem = menuItem;
if (_this3.currentItem !== _this3.lastActiveItem) {
_this3.$emit('itemchanged', event, _this3.currentItem, _this3.lastActiveItem);
_this3.lastActiveItem = _this3.currentItem;
}
}
if (_this3.modifyUrl) {
Object(_utils__WEBPACK_IMPORTED_MODULE_5__["pushHashToUrl"])(Object(_utils__WEBPACK_IMPORTED_MODULE_5__["getSectionIdFromElement"])(menuItem));
}
case 12:
case "end":
return _context.stop();
}
}
}, _callee);
}))();
},
/**
* Scrolls the page to the given target element.
*/
scrollTo: function scrollTo(target) {
var _this4 = this;
return new Promise(function (resolve) {
var targetDistanceFromTop = _this4.getOffsetTop(target);
var startingY = _this4.scrollContainer.getDistanceFromTop();
var distanceFromTarget = targetDistanceFromTop - startingY;
var easing = _this4.bezierEasing.apply(_this4, _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(_this4.cubicBezierArray));
var startingTime = null;
var step = function step(currentTime) {
if (!startingTime) startingTime = currentTime;
var progress = currentTime - startingTime;
var progressPercentage = progress / _this4.duration;
if (progress >= _this4.duration) progress = _this4.duration;
if (progressPercentage >= 1) progressPercentage = 1;
var offset = _this4.scrollOffset || _this4.offset;
var perTick = startingY + easing(progressPercentage) * (distanceFromTarget - offset);
_this4.scrollContainer.scrollTo(0, perTick);
if (progress < _this4.duration) {
_this4.scrollAnimationFrame = window.requestAnimationFrame(step);
} else {
resolve();
}
};
window.requestAnimationFrame(step);
});
},
/**
* Gets the top offset position of an element in the document.
*/
getOffsetTop: function getOffsetTop(element) {
var yPosition = 0;
var nextElement = element;
while (nextElement) {
yPosition += nextElement.offsetTop;
nextElement = nextElement.offsetParent;
}
if (this.scrollContainer.getOffsetTop()) {
yPosition -= this.scrollContainer.getOffsetTop();
}
return yPosition;
},
/**
* Removes the active class from all scrollactive items.
*/
removeActiveClass: function removeActiveClass() {
var _this5 = this;
// Must be called with 'call' to prevent bugs on some devices
Object(_utils__WEBPACK_IMPORTED_MODULE_5__["forEach"])(this.items, function (_ref2) {
var menuElement = _ref2.menuElement;
menuElement.classList.remove(_this5.activeClass);
});
},
/**
* Scrolls the page to the element passed as a hash in URL, preventing weird native scroll
* jumps while maintaining the hash in the URL.
*/
scrollToHashElement: function scrollToHashElement() {
var _this6 = this;
var hash = window.location.hash;
if (!hash) return;
var hashElement = document.getElementById(Object(_utils__WEBPACK_IMPORTED_MODULE_5__["getIdFromHash"])(hash));
if (!hashElement) return;
window.location.hash = ''; // Clears the hash to prevent scroll from jumping
setTimeout(function () {
var yPos = hashElement.offsetTop - _this6.offset;
_this6.scrollContainer.scrollTo(0, yPos); // Sets the hash back with pushState so it won't jump to the element ignoring the offset
Object(_utils__WEBPACK_IMPORTED_MODULE_5__["pushHashToUrl"])(hash);
}, 0);
}
}
});
/***/ }),
/***/ "./node_modules/bezier-easing/src/index.js":
/*!*************************************************!*\
!*** ./node_modules/bezier-easing/src/index.js ***!
\*************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
/**
* https://github.com/gre/bezier-easing
* BezierEasing - use bezier curve for transition easing function
* by Gaëtan Renaudeau 2014 - 2015 – MIT License
*/
// These values are established by empiricism with tests (tradeoff: performance VS precision)
var NEWTON_ITERATIONS = 4;
var NEWTON_MIN_SLOPE = 0.001;
var SUBDIVISION_PRECISION = 0.0000001;
var SUBDIVISION_MAX_ITERATIONS = 10;
var kSplineTableSize = 11;
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
var float32ArraySupported = typeof Float32Array === 'function';
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
function C (aA1) { return 3.0 * aA1; }
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
function binarySubdivide (aX, aA, aB, mX1, mX2) {
var currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) {
aB = currentT;
} else {
aA = currentT;
}
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
return currentT;
}
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
var currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) {
return aGuessT;
}
var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
function LinearEasing (x) {
return x;
}
module.exports = function bezier (mX1, mY1, mX2, mY2) {
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
throw new Error('bezier x values must be in [0, 1] range');
}
if (mX1 === mY1 && mX2 === mY2) {
return LinearEasing;
}
// Precompute samples table
var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
for (var i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
function getTForX (aX) {
var intervalStart = 0.0;
var currentSample = 1;
var lastSample = kSplineTableSize - 1;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
}
--currentSample;
// Interpolate to provide an initial guess for t
var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
var guessForT = intervalStart + dist * kSampleStepSize;
var initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= NEWTON_MIN_SLOPE) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
}
}
return function BezierEasing (x) {
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
if (x === 0) {
return 0;
}
if (x === 1) {
return 1;
}
return calcBezier(getTForX(x), mY1, mY2);
};
};
/***/ }),
/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/sandbox/normalize.scss":
/*!*****************************************************************************************************************!*\
!*** ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/sandbox/normalize.scss ***!
\*****************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
// Imports
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
exports = ___CSS_LOADER_API_IMPORT___(false);
// Module
exports.push([module.i, "/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */\n/* Document\n ========================================================================== */\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in\n * IE on Windows Phone and in iOS.\n */\nhtml {\n line-height: 1.15;\n /* 1 */\n -ms-text-size-adjust: 100%;\n /* 2 */\n -webkit-text-size-adjust: 100%;\n /* 2 */ }\n\n/* Sections\n ========================================================================== */\n/**\n * Remove the margin in all browsers (opinionated).\n */\nbody {\n margin: 0; }\n\n/**\n * Add the correct display in IE 9-.\n */\narticle,\naside,\nfooter,\nheader,\nnav,\nsection {\n display: block; }\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\nh1 {\n font-size: 2em;\n margin: 0.67em 0; }\n\n/* Grouping content\n ========================================================================== */\n/**\n * Add the correct display in IE 9-.\n * 1. Add the correct display in IE.\n */\nfigcaption,\nfigure,\nmain {\n /* 1 */\n display: block; }\n\n/**\n * Add the correct margin in IE 8.\n */\nfigure {\n margin: 1em 40px; }\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\nhr {\n box-sizing: content-box;\n /* 1 */\n height: 0;\n /* 1 */\n overflow: visible;\n /* 2 */ }\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\npre {\n font-family: monospace, monospace;\n /* 1 */\n font-size: 1em;\n /* 2 */ }\n\n/* Text-level semantics\n ========================================================================== */\n/**\n * 1. Remove the gray background on active links in IE 10.\n * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.\n */\na {\n background-color: transparent;\n /* 1 */\n -webkit-text-decoration-skip: objects;\n /* 2 */ }\n\n/**\n * 1. Remove the bottom border in Chrome 57- and Firefox 39-.\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\nabbr[title] {\n border-bottom: none;\n /* 1 */\n text-decoration: underline;\n /* 2 */\n text-decoration: underline dotted;\n /* 2 */ }\n\n/**\n * Prevent the duplicate application of `bolder` by the next rule in Safari 6.\n */\nb,\nstrong {\n font-weight: inherit; }\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\nb,\nstrong {\n font-weight: bolder; }\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n /* 1 */\n font-size: 1em;\n /* 2 */ }\n\n/**\n * Add the correct font style in Android 4.3-.\n */\ndfn {\n font-style: italic; }\n\n/**\n * Add the correct background and color in IE 9-.\n */\nmark {\n background-color: #ff0;\n color: #000; }\n\n/**\n * Add the correct font size in all browsers.\n */\nsmall {\n font-size: 80%; }\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline; }\n\nsub {\n bottom: -0.25em; }\n\nsup {\n top: -0.5em; }\n\n/* Embedded content\n ========================================================================== */\n/**\n * Add the correct display in IE 9-.\n */\naudio,\nvideo {\n display: inline-block; }\n\n/**\n * Add the correct display in iOS 4-7.\n */\naudio:not([controls]) {\n display: none;\n height: 0; }\n\n/**\n * Remove the border on images inside links in IE 10-.\n */\nimg {\n border-style: none; }\n\n/**\n * Hide the overflow in IE.\n */\nsvg:not(:root) {\n overflow: hidden; }\n\n/* Forms\n ========================================================================== */\n/**\n * 1. Change the font styles in all browsers (opinionated).\n * 2. Remove the margin in Firefox and Safari.\n */\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: sans-serif;\n /* 1 */\n font-size: 100%;\n /* 1 */\n line-height: 1.15;\n /* 1 */\n margin: 0;\n /* 2 */ }\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\nbutton,\ninput {\n /* 1 */\n overflow: visible; }\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\nbutton,\nselect {\n /* 1 */\n text-transform: none; }\n\n/**\n * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n * controls in Android 4.\n * 2. Correct the inability to style clickable types in iOS and Safari.\n */\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n /* 2 */ }\n\n/**\n * Remove the inner border and padding in Firefox.\n */\nbutton::-moz-focus-inner,\n[type='button']::-moz-focus-inner,\n[type='reset']::-moz-focus-inner,\n[type='submit']::-moz-focus-inner {\n border-style: none;\n padding: 0; }\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\nbutton:-moz-focusring,\n[type='button']:-moz-focusring,\n[type='reset']:-moz-focusring,\n[type='submit']:-moz-focusring {\n outline: 1px dotted ButtonText; }\n\n/**\n * Correct the padding in Firefox.\n */\nfieldset {\n padding: 0.35em 0.75em 0.625em; }\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\nlegend {\n box-sizing: border-box;\n /* 1 */\n color: inherit;\n /* 2 */\n display: table;\n /* 1 */\n max-width: 100%;\n /* 1 */\n padding: 0;\n /* 3 */\n white-space: normal;\n /* 1 */ }\n\n/**\n * 1. Add the correct display in IE 9-.\n * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\nprogress {\n display: inline-block;\n /* 1 */\n vertical-align: baseline;\n /* 2 */ }\n\n/**\n * Remove the default vertical scrollbar in IE.\n */\ntextarea {\n overflow: auto; }\n\n/**\n * 1. Add the correct box sizing in IE 10-.\n * 2. Remove the padding in IE 10-.\n */\n[type='checkbox'],\n[type='radio'] {\n box-sizing: border-box;\n /* 1 */\n padding: 0;\n /* 2 */ }\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n[type='number']::-webkit-inner-spin-button,\n[type='number']::-webkit-outer-spin-button {\n height: auto; }\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n[type='search'] {\n -webkit-appearance: textfield;\n /* 1 */\n outline-offset: -2px;\n /* 2 */ }\n\n/**\n * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.\n */\n[type='search']::-webkit-search-cancel-button,\n[type='search']::-webkit-search-decoration {\n -webkit-appearance: none; }\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n::-webkit-file-upload-button {\n -webkit-appearance: button;\n /* 1 */\n font: inherit;\n /* 2 */ }\n\n/* Interactive\n ========================================================================== */\n/*\n * Add the correct display in IE 9-.\n * 1. Add the correct display in Edge, IE, and Firefox.\n */\ndetails,\nmenu {\n display: block; }\n\n/*\n * Add the correct display in all browsers.\n */\nsummary {\n display: list-item; }\n\n/* Scripting\n ========================================================================== */\n/**\n * Add the correct display in IE 9-.\n */\ncanvas {\n display: inline-block; }\n\n/**\n * Add the correct display in IE.\n */\ntemplate {\n display: none; }\n\n/* Hidden\n ========================================================================== */\n/**\n * Add the correct display in IE 10-.\n */\n[hidden] {\n display: none; }\n", ""]);
// Exports
module.exports = exports;
/***/ }),
/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/sandbox/sandbox.scss":
/*!***************************************************************************************************************!*\
!*** ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/sandbox/sandbox.scss ***!
\***************************************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
// Imports
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
exports = ___CSS_LOADER_API_IMPORT___(false);
// Module
exports.push([module.i, ".nav.is-fixed {\n position: fixed;\n left: 0;\n right: 0; }\n .nav.is-fixed .is-active {\n color: #00d1b2; }\n\n.section {\n padding-top: 100px; }\n\n.buttons {\n position: fixed;\n z-index: 10;\n top: 100px;\n right: 100px;\n padding: 15px 30px;\n border-radius: 10px;\n background-color: #7a7a7a;\n background-color: #fff; }\n .buttons label {\n display: block; }\n .buttons input,\n .buttons button {\n display: block;\n width: 100%;\n height: 42px;\n padding: 10px 20px;\n margin-top: 15px;\n margin-bottom: 15px;\n border: 0;\n border: 2px solid #00d1b2;\n border-radius: 10px;\n font-weight: 600;\n outline: 0;\n transition: all 0.1s; }\n .buttons button {\n background-color: #00d1b2;\n cursor: pointer;\n color: #fff; }\n .buttons button:hover {\n background-color: #fff;\n color: #00d1b2; }\n", ""]);
// Exports
module.exports = exports;
/***/ }),
/***/ "./node_modules/css-loader/dist/runtime/api.js":
/*!*****************************************************!*\
!*** ./node_modules/css-loader/dist/runtime/api.js ***!
\*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
// eslint-disable-next-line func-names
module.exports = function (useSourceMap) {
var list = []; // return the list of modules as css string
list.toString = function toString() {
return this.map(function (item) {
var content = cssWithMappingToString(item, useSourceMap);
if (item[2]) {
return "@media ".concat(item[2], " {").concat(content, "}");
}
return content;
}).join('');
}; // import a list of modules into the list
// eslint-disable-next-line func-names
list.i = function (modules, mediaQuery, dedupe) {
if (typeof modules === 'string') {
// eslint-disable-next-line no-param-reassign
modules = [[null, modules, '']];
}
var alreadyImportedModules = {};
if (dedupe) {
for (var i = 0; i < this.length; i++) {
// eslint-disable-next-line prefer-destructuring
var id = this[i][0];
if (id != null) {
alreadyImportedModules[id] = true;
}
}
}
for (var _i = 0; _i < modules.length; _i++) {
var item = [].concat(modules[_i]);
if (dedupe && alreadyImportedModules[item[0]]) {
// eslint-disable-next-line no-continue
continue;
}
if (mediaQuery) {
if (!item[2]) {
item[2] = mediaQuery;
} else {
item[2] = "".concat(mediaQuery, " and ").concat(item[2]);
}
}
list.push(item);
}
};
return list;
};
function cssWithMappingToString(item, useSourceMap) {
var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring
var cssMapping = item[3];
if (!cssMapping) {
return content;
}
if (useSourceMap && typeof btoa === 'function') {
var sourceMapping = toComment(cssMapping);
var sourceURLs = cssMapping.sources.map(function (source) {
return "/*# sourceURL=".concat(cssMapping.sourceRoot || '').concat(source, " */");
});
return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
}
return [content].join('\n');
} // Adapted from convert-source-map (MIT)
function toComment(sourceMap) {
// eslint-disable-next-line no-undef
var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
return "/*# ".concat(data, " */");
}
/***/ }),
/***/ "./node_modules/regenerator-runtime/runtime.js":
/*!*****************************************************!*\
!*** ./node_modules/regenerator-runtime/runtime.js ***!
\*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var runtime = (function (exports) {
"use strict";
var Op = Object.prototype;
var hasOwn = Op.hasOwnProperty;
var undefined; // More compressible than void 0.
var $Symbol = typeof Symbol === "function" ? Symbol : {};
var iteratorSymbol = $Symbol.iterator || "@@iterator";
var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
function wrap(innerFn, outerFn, self, tryLocsList) {
// If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
var generator = Object.create(protoGenerator.prototype);
var context = new Context(tryLocsList || []);
// The ._invoke method unifies the implementations of the .next,
// .throw, and .return methods.
generator._invoke = makeInvokeMethod(innerFn, self, context);
return generator;
}
exports.wrap = wrap;
// Try/catch helper to minimize deoptimizations. Returns a completion
// record like context.tryEntries[i].completion. This interface could
// have been (and was previously) designed to take a closure to be
// invoked without arguments, but in all the cases we care about we
// already have an existing method we want to call, so there's no need
// to create a new function object. We can even get away with assuming
// the method takes exactly one argument, since that happens to be true
// in every case, so we don't have to touch the arguments object. The
// only additional allocation required is the completion record, which
// has a stable shape and so hopefully should be cheap to allocate.
function tryCatch(fn, obj, arg) {
try {
return { type: "normal", arg: fn.call(obj, arg) };
} catch (err) {
return { type: "throw", arg: err };
}
}
var GenStateSuspendedStart = "suspendedStart";
var GenStateSuspendedYield = "suspendedYield";
var GenStateExecuting = "executing";
var GenStateCompleted = "completed";
// Returning this object from the innerFn has the same effect as
// breaking out of the dispatch switch statement.
var ContinueSentinel = {};
// Dummy constructor functions that we use as the .constructor and
// .constructor.prototype properties for functions that return Generator
// objects. For full spec compliance, you may wish to configure your
// minifier not to mangle the names of these two functions.
function Generator() {}
function GeneratorFunction() {}
function GeneratorFunctionPrototype() {}
// This is a polyfill for %IteratorPrototype% for environments that
// don't natively support it.
var IteratorPrototype = {};
IteratorPrototype[iteratorSymbol] = function () {
return this;
};
var getProto = Object.getPrototypeOf;
var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
if (NativeIteratorPrototype &&
NativeIteratorPrototype !== Op &&
hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
// This environment has a native %IteratorPrototype%; use it instead
// of the polyfill.
IteratorPrototype = NativeIteratorPrototype;
}
var Gp = GeneratorFunctionPrototype.prototype =
Generator.prototype = Object.create(IteratorPrototype);
GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
GeneratorFunctionPrototype.constructor = GeneratorFunction;
GeneratorFunctionPrototype[toStringTagSymbol] =
GeneratorFunction.displayName = "GeneratorFunction";
// Helper for defining the .next, .throw, and .return methods of the
// Iterator interface in terms of a single ._invoke method.
function defineIteratorMethods(prototype) {
["next", "throw", "return"].forEach(function(method) {
prototype[method] = function(arg) {
return this._invoke(method, arg);
};
});
}
exports.isGeneratorFunction = function(genFun) {
v