UNPKG

@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
/******/ (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