// // SmoothScroll for websites v1.4.0 (Balazs Galambosi) // http://www.smoothscroll.net/ // // Licensed under the terms of the MIT license. // // You may use it in your theme if you credit me. // It is also free to use on any individual website. // // Exception: // The only restriction is to not publish any // extension for browsers or native application // without getting a written permission first. // (function () { // Scroll Variables (tweakable) var defaultOptions = { // Scrolling Core frameRate: 150, // [Hz] animationTime: 400, // [ms] stepSize: 100, // [px] // Pulse (less tweakable) // ratio of "tail" to "acceleration" pulseAlgorithm: true, pulseScale: 4, pulseNormalize: 1, // Acceleration accelerationDelta: 50, // 50 accelerationMax: 3, // 3 // Keyboard Settings keyboardSupport: true, // option arrowScroll: 50, // [px] // Other touchpadSupport: false, // ignore touchpad by default fixedBackground: true, excluded: '' }; var options = defaultOptions; // Other Variables var isExcluded = false; var isFrame = false; var direction = { x: 0, y: 0 }; var initDone = false; var root = document.documentElement; var activeElement; var observer; var refreshSize; var deltaBuffer = []; var isMac = /^Mac/.test(navigator.platform); var key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36 }; /*********************************************** * INITIALIZE ***********************************************/ /** * Tests if smooth scrolling is allowed. Shuts down everything if not. */ function initTest() { if (options.keyboardSupport) { addEvent('keydown', keydown); } } /** * Sets up scrolls array, determines if frames are involved. */ function init() { if (initDone || !document.body) return; initDone = true; var body = document.body; var html = document.documentElement; var windowHeight = window.innerHeight; var scrollHeight = body.scrollHeight; // check compat mode for root element root = (document.compatMode.indexOf('CSS') >= 0) ? html : body; activeElement = body; initTest(); // Checks if this script is running in a frame if (top != self) { isFrame = true; } /** * Please duplicate this radar for a Safari fix! * rdar://22376037 * https://openradar.appspot.com/radar?id=4965070979203072 * * Only applies to Safari now, Chrome fixed it in v45: * This fixes a bug where the areas left and right to * the content does not trigger the onmousewheel event * on some pages. e.g.: html, body { height: 100% } */ else if (scrollHeight > windowHeight && (body.offsetHeight <= windowHeight || html.offsetHeight <= windowHeight)) { var fullPageElem = document.createElement('div'); fullPageElem.style.cssText = 'position:absolute; z-index:-10000; ' + 'top:0; left:0; right:0; height:' + root.scrollHeight + 'px'; document.body.appendChild(fullPageElem); // DOM changed (throttled) to fix height var pendingRefresh; refreshSize = function () { if (pendingRefresh) return; // could also be: clearTimeout(pendingRefresh); pendingRefresh = setTimeout(function () { if (isExcluded) return; // could be running after cleanup fullPageElem.style.height = '0'; fullPageElem.style.height = root.scrollHeight + 'px'; pendingRefresh = null; }, 500); // act rarely to stay fast }; setTimeout(refreshSize, 10); addEvent('resize', refreshSize); // TODO: attributeFilter? var config = { attributes: true, childList: true, characterData: false // subtree: true }; observer = new MutationObserver(refreshSize); observer.observe(body, config); if (root.offsetHeight <= windowHeight) { var clearfix = document.createElement('div'); clearfix.style.clear = 'both'; body.appendChild(clearfix); } } // disable fixed background if (!options.fixedBackground && !isExcluded) { body.style.backgroundAttachment = 'scroll'; html.style.backgroundAttachment = 'scroll'; } } /** * Removes event listeners and other traces left on the page. */ function cleanup() { observer && observer.disconnect(); removeEvent(wheelEvent, wheel); removeEvent('mousedown', mousedown); removeEvent('keydown', keydown); removeEvent('resize', refreshSize); removeEvent('load', init); } /************************************************ * SCROLLING ************************************************/ var que = []; var pending = false; var lastScroll = Date.now(); /** * Pushes scroll actions to the scrolling queue. */ function scrollArray(elem, left, top) { directionCheck(left, top); if (options.accelerationMax != 1) { var now = Date.now(); var elapsed = now - lastScroll; if (elapsed < options.accelerationDelta) { var factor = (1 + (50 / elapsed)) / 2; if (factor > 1) { factor = Math.min(factor, options.accelerationMax); left *= factor; top *= factor; } } lastScroll = Date.now(); } // push a scroll command que.push({ x: left, y: top, lastX: (left < 0) ? 0.99 : -0.99, lastY: (top < 0) ? 0.99 : -0.99, start: Date.now() }); // don't act if there's a pending queue if (pending) { return; } var scrollWindow = (elem === document.body); var step = function (time) { var now = Date.now(); var scrollX = 0; var scrollY = 0; for (var i = 0; i < que.length; i++) { var item = que[i]; var elapsed = now - item.start; var finished = (elapsed >= options.animationTime); // scroll position: [0, 1] var position = (finished) ? 1 : elapsed / options.animationTime; // easing [optional] if (options.pulseAlgorithm) { position = pulse(position); } // only need the difference var x = (item.x * position - item.lastX) >> 0; var y = (item.y * position - item.lastY) >> 0; // add this to the total scrolling scrollX += x; scrollY += y; // update last values item.lastX += x; item.lastY += y; // delete and step back if it's over if (finished) { que.splice(i, 1); i--; } } // scroll left and top if (scrollWindow) { window.scrollBy(scrollX, scrollY); } else { if (scrollX) elem.scrollLeft += scrollX; if (scrollY) elem.scrollTop += scrollY; } // clean up if there's nothing left to do if (!left && !top) { que = []; } if (que.length) { requestFrame(step, elem, (1000 / options.frameRate + 1)); } else { pending = false; } }; // start a new queue of actions requestFrame(step, elem, 0); pending = true; } /*********************************************** * EVENTS ***********************************************/ /** * Mouse wheel handler. * @param {Object} event */ function wheel(event) { if (!initDone) { init(); } var target = event.target; var overflowing = overflowingAncestor(target); // use default if there's no overflowing // element or default action is prevented // or it's a zooming event with CTRL if (!overflowing || event.defaultPrevented || event.ctrlKey) { return true; } // leave embedded content alone (flash & pdf) if (isNodeName(activeElement, 'embed') || (isNodeName(target, 'embed') && /\.pdf/i.test(target.src)) || isNodeName(activeElement, 'object')) { return true; } var deltaX = -event.wheelDeltaX || event.deltaX || 0; var deltaY = -event.wheelDeltaY || event.deltaY || 0; if (isMac) { if (event.wheelDeltaX && isDivisible(event.wheelDeltaX, 120)) { deltaX = -120 * (event.wheelDeltaX / Math.abs(event.wheelDeltaX)); } if (event.wheelDeltaY && isDivisible(event.wheelDeltaY, 120)) { deltaY = -120 * (event.wheelDeltaY / Math.abs(event.wheelDeltaY)); } } // use wheelDelta if deltaX/Y is not available if (!deltaX && !deltaY) { deltaY = -event.wheelDelta || 0; } // line based scrolling (Firefox mostly) if (event.deltaMode === 1) { deltaX *= 40; deltaY *= 40; } // check if it's a touchpad scroll that should be ignored if (!options.touchpadSupport && isTouchpad(deltaY)) { return true; } // scale by step size // delta is 120 most of the time // synaptics seems to send 1 sometimes if (Math.abs(deltaX) > 1.2) { deltaX *= options.stepSize / 120; } if (Math.abs(deltaY) > 1.2) { deltaY *= options.stepSize / 120; } scrollArray(overflowing, deltaX, deltaY); event.preventDefault(); scheduleClearCache(); } /** * Keydown event handler. * @param {Object} event */ function keydown(event) { var target = event.target; var modifier = event.ctrlKey || event.altKey || event.metaKey || (event.shiftKey && event.keyCode !== key.spacebar); // our own tracked active element could've been removed from the DOM if (!document.contains(activeElement)) { activeElement = document.activeElement; } // do nothing if user is editing text // or using a modifier key (except shift) // or in a dropdown // or inside interactive elements var inputNodeNames = /^(textarea|select|embed|object)$/i; var buttonTypes = /^(button|submit|radio|checkbox|file|color|image)$/i; if (inputNodeNames.test(target.nodeName) || isNodeName(target, 'input') && !buttonTypes.test(target.type) || isNodeName(activeElement, 'video') || isInsideYoutubeVideo(event) || target.isContentEditable || event.defaultPrevented || modifier) { return true; } // spacebar should trigger button press if ((isNodeName(target, 'button') || isNodeName(target, 'input') && buttonTypes.test(target.type)) && event.keyCode === key.spacebar) { return true; } var shift, x = 0, y = 0; var elem = overflowingAncestor(activeElement); var clientHeight = elem.clientHeight; if (elem == document.body) { clientHeight = window.innerHeight; } switch (event.keyCode) { case key.up: y = -options.arrowScroll; break; case key.down: y = options.arrowScroll; break; case key.spacebar: // (+ shift) shift = event.shiftKey ? 1 : -1; y = -shift * clientHeight * 0.9; break; case key.pageup: y = -clientHeight * 0.9; break; case key.pagedown: y = clientHeight * 0.9; break; case key.home: y = -elem.scrollTop; break; case key.end: var damt = elem.scrollHeight - elem.scrollTop - clientHeight; y = (damt > 0) ? damt + 10 : 0; break; case key.left: x = -options.arrowScroll; break; case key.right: x = options.arrowScroll; break; default: return true; // a key we don't care about } scrollArray(elem, x, y); event.preventDefault(); scheduleClearCache(); } /** * Mousedown event only for updating activeElement */ function mousedown(event) { activeElement = event.target; } /*********************************************** * OVERFLOW ***********************************************/ var uniqueID = (function () { var i = 0; return function (el) { return el.uniqueID || (el.uniqueID = i++); }; })(); var cache = {}; // cleared out after a scrolling session var clearCacheTimer; //setInterval(function () { cache = {}; }, 10 * 1000); function scheduleClearCache() { clearTimeout(clearCacheTimer); clearCacheTimer = setInterval(function () { cache = {}; }, 1 * 1000); } function setCache(elems, overflowing) { for (var i = elems.length; i--;) cache[uniqueID(elems[i])] = overflowing; return overflowing; } // (body) (root) // | hidden | visible | scroll | auto | // hidden | no | no | YES | YES | // visible | no | YES | YES | YES | // scroll | no | YES | YES | YES | // auto | no | YES | YES | YES | function overflowingAncestor(el) { var elems = []; var body = document.body; var rootScrollHeight = root.scrollHeight; do { var cached = cache[uniqueID(el)]; if (cached) { return setCache(elems, cached); } elems.push(el); if (rootScrollHeight === el.scrollHeight) { var topOverflowsNotHidden = overflowNotHidden(root) && overflowNotHidden(body); var isOverflowCSS = topOverflowsNotHidden || overflowAutoOrScroll(root); if (isFrame && isContentOverflowing(root) || !isFrame && isOverflowCSS) { return setCache(elems, getScrollRoot()); } } else if (isContentOverflowing(el) && overflowAutoOrScroll(el)) { return setCache(elems, el); } } while (el = el.parentElement); } function isContentOverflowing(el) { return (el.clientHeight + 10 < el.scrollHeight); } // typically for and function overflowNotHidden(el) { var overflow = getComputedStyle(el, '').getPropertyValue('overflow-y'); return (overflow !== 'hidden'); } // for all other elements function overflowAutoOrScroll(el) { var overflow = getComputedStyle(el, '').getPropertyValue('overflow-y'); return (overflow === 'scroll' || overflow === 'auto'); } /*********************************************** * HELPERS ***********************************************/ function addEvent(type, fn) { window.addEventListener(type, fn, false); } function removeEvent(type, fn) { window.removeEventListener(type, fn, false); } function isNodeName(el, tag) { return (el.nodeName || '').toLowerCase() === tag.toLowerCase(); } function directionCheck(x, y) { x = (x > 0) ? 1 : -1; y = (y > 0) ? 1 : -1; if (direction.x !== x || direction.y !== y) { direction.x = x; direction.y = y; que = []; lastScroll = 0; } } var deltaBufferTimer; if (window.localStorage && localStorage.SS_deltaBuffer) { deltaBuffer = localStorage.SS_deltaBuffer.split(','); } function isTouchpad(deltaY) { if (!deltaY) return; if (!deltaBuffer.length) { deltaBuffer = [deltaY, deltaY, deltaY]; } deltaY = Math.abs(deltaY) deltaBuffer.push(deltaY); deltaBuffer.shift(); clearTimeout(deltaBufferTimer); deltaBufferTimer = setTimeout(function () { if (window.localStorage) { localStorage.SS_deltaBuffer = deltaBuffer.join(','); } }, 1000); return !allDeltasDivisableBy(120) && !allDeltasDivisableBy(100); } function isDivisible(n, divisor) { return (Math.floor(n / divisor) == n / divisor); } function allDeltasDivisableBy(divisor) { return (isDivisible(deltaBuffer[0], divisor) && isDivisible(deltaBuffer[1], divisor) && isDivisible(deltaBuffer[2], divisor)); } function isInsideYoutubeVideo(event) { var elem = event.target; var isControl = false; if (document.URL.indexOf('www.youtube.com/watch') != -1) { do { isControl = (elem.classList && elem.classList.contains('html5-video-controls')); if (isControl) break; } while (elem = elem.parentNode); } return isControl; } var requestFrame = (function () { return (window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback, element, delay) { window.setTimeout(callback, delay || (1000 / 60)); }); })(); var MutationObserver = (window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver); var getScrollRoot = (function () { var SCROLL_ROOT; return function () { if (!SCROLL_ROOT) { var dummy = document.createElement('div'); dummy.style.cssText = 'height:10000px;width:1px;'; document.body.appendChild(dummy); var bodyScrollTop = document.body.scrollTop; var docElScrollTop = document.documentElement.scrollTop; window.scrollBy(0, 1); if (document.body.scrollTop != bodyScrollTop) (SCROLL_ROOT = document.body); else (SCROLL_ROOT = document.documentElement); window.scrollBy(0, -1); document.body.removeChild(dummy); } return SCROLL_ROOT; }; })(); /*********************************************** * PULSE (by Michael Herf) ***********************************************/ /** * Viscous fluid with a pulse for part and decay for the rest. * - Applies a fixed force over an interval (a damped acceleration), and * - Lets the exponential bleed away the velocity over a longer interval * - Michael Herf, http://stereopsis.com/stopping/ */ function pulse_(x) { var val, start, expx; // test x = x * options.pulseScale; if (x < 1) { // acceleartion val = x - (1 - Math.exp(-x)); } else { // tail // the previous animation ended here: start = Math.exp(-1); // simple viscous drag x -= 1; expx = 1 - Math.exp(-x); val = start + (expx * (1 - start)); } return val * options.pulseNormalize; } function pulse(x) { if (x >= 1) return 1; if (x <= 0) return 0; if (options.pulseNormalize == 1) { options.pulseNormalize /= pulse_(1); } return pulse_(x); } /*********************************************** * FIRST RUN ***********************************************/ var userAgent = window.navigator.userAgent; var isEdge = /Edge/.test(userAgent); // thank you MS var isChrome = /chrome/i.test(userAgent) && !isEdge; var isSafari = /safari/i.test(userAgent) && !isEdge; var isMobile = /mobile/i.test(userAgent); var isEnabledForBrowser = (isChrome || isSafari) && !isMobile; var wheelEvent; if ('onwheel' in document.createElement('div')) wheelEvent = 'wheel'; else if ('onmousewheel' in document.createElement('div')) wheelEvent = 'mousewheel'; if (wheelEvent && isEnabledForBrowser) { addEvent(wheelEvent, wheel); addEvent('mousedown', mousedown); addEvent('load', init); } /*********************************************** * PUBLIC INTERFACE ***********************************************/ function SmoothScroll(optionsToSet) { for (var key in optionsToSet) if (defaultOptions.hasOwnProperty(key)) options[key] = optionsToSet[key]; } SmoothScroll.destroy = cleanup; if (window.SmoothScrollOptions) // async API SmoothScroll(window.SmoothScrollOptions) if ('object' == typeof exports) module.exports = SmoothScroll; else window.SmoothScroll = SmoothScroll; })(); /* * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ * * Uses the built in easing capabilities added In jQuery 1.1 * to offer multiple easing options * * TERMS OF USE - jQuery Easing * * Open source under the BSD License. * * Copyright © 2008 George McGinley Smith * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the author nor the names of contributors may be used to endorse * or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ // t: current time, b: begInnIng value, c: change In value, d: duration jQuery.easing['jswing'] = jQuery.easing['swing']; jQuery.extend( jQuery.easing, { def: 'easeOutQuad', swing: function (x, t, b, c, d) { //alert(jQuery.easing.default); return jQuery.easing[jQuery.easing.def](x, t, b, c, d); }, easeInQuad: function (x, t, b, c, d) { return c*(t/=d)*t + b; }, easeOutQuad: function (x, t, b, c, d) { return -c *(t/=d)*(t-2) + b; }, easeInOutQuad: function (x, t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t + b; return -c/2 * ((--t)*(t-2) - 1) + b; }, easeInCubic: function (x, t, b, c, d) { return c*(t/=d)*t*t + b; }, easeOutCubic: function (x, t, b, c, d) { return c*((t=t/d-1)*t*t + 1) + b; }, easeInOutCubic: function (x, t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t*t + b; return c/2*((t-=2)*t*t + 2) + b; }, easeInQuart: function (x, t, b, c, d) { return c*(t/=d)*t*t*t + b; }, easeOutQuart: function (x, t, b, c, d) { return -c * ((t=t/d-1)*t*t*t - 1) + b; }, easeInOutQuart: function (x, t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t*t*t + b; return -c/2 * ((t-=2)*t*t*t - 2) + b; }, easeInQuint: function (x, t, b, c, d) { return c*(t/=d)*t*t*t*t + b; }, easeOutQuint: function (x, t, b, c, d) { return c*((t=t/d-1)*t*t*t*t + 1) + b; }, easeInOutQuint: function (x, t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; return c/2*((t-=2)*t*t*t*t + 2) + b; }, easeInSine: function (x, t, b, c, d) { return -c * Math.cos(t/d * (Math.PI/2)) + c + b; }, easeOutSine: function (x, t, b, c, d) { return c * Math.sin(t/d * (Math.PI/2)) + b; }, easeInOutSine: function (x, t, b, c, d) { return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; }, easeInExpo: function (x, t, b, c, d) { return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; }, easeOutExpo: function (x, t, b, c, d) { return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; }, easeInOutExpo: function (x, t, b, c, d) { if (t==0) return b; if (t==d) return b+c; if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; }, easeInCirc: function (x, t, b, c, d) { return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; }, easeOutCirc: function (x, t, b, c, d) { return c * Math.sqrt(1 - (t=t/d-1)*t) + b; }, easeInOutCirc: function (x, t, b, c, d) { if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; }, easeInElastic: function (x, t, b, c, d) { var s=1.70158;var p=0;var a=c; if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; if (a < Math.abs(c)) { a=c; var s=p/4; } else var s = p/(2*Math.PI) * Math.asin (c/a); return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; }, easeOutElastic: function (x, t, b, c, d) { var s=1.70158;var p=0;var a=c; if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; if (a < Math.abs(c)) { a=c; var s=p/4; } else var s = p/(2*Math.PI) * Math.asin (c/a); return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; }, easeInOutElastic: function (x, t, b, c, d) { var s=1.70158;var p=0;var a=c; if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); if (a < Math.abs(c)) { a=c; var s=p/4; } else var s = p/(2*Math.PI) * Math.asin (c/a); if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; }, easeInBack: function (x, t, b, c, d, s) { if (s == undefined) s = 1.70158; return c*(t/=d)*t*((s+1)*t - s) + b; }, easeOutBack: function (x, t, b, c, d, s) { if (s == undefined) s = 1.70158; return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; }, easeInOutBack: function (x, t, b, c, d, s) { if (s == undefined) s = 1.70158; if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; }, easeInBounce: function (x, t, b, c, d) { return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b; }, easeOutBounce: function (x, t, b, c, d) { if ((t/=d) < (1/2.75)) { return c*(7.5625*t*t) + b; } else if (t < (2/2.75)) { return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; } else if (t < (2.5/2.75)) { return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; } else { return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; } }, easeInOutBounce: function (x, t, b, c, d) { if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; } }); // jQuery for page scrolling feature - requires jQuery Easing plugin $('a.page-scroll').on('click', function (event) { var $anchor = $(this); $('html, body').stop().animate({ scrollTop: ($($anchor.attr('href')).offset().top) }, 700, 'easeInOutSine'); event.preventDefault(); }); /* Page Preloader Script */ $(window).load(function () { $('#preloader').delay(100).fadeOut('slow'); $('html,body').addClass('add-oveflow'); }); jQuery(document).ready(function ($) { navigation_menu(); goto_top_page(); }); /* Animated Navigation Menu */ function navigation_menu() { (function ($) { var isLateralNavAnimating = false; $('.nav-button').on('click', function (event) { event.preventDefault(); if (!isLateralNavAnimating) { if ($(this).parents('.csstransitions').length > 0) isLateralNavAnimating = true; $('html').toggleClass('scroll-hide'); $('.goto-top').toggleClass('goto-hide'); $('body').toggleClass('navigation-is-open'); $('.nav-wrapper').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function () { isLateralNavAnimating = false; }); } }); })(jQuery); } /* Script for Go to top */ function goto_top_page() { (function ($) { var offset = 600, /* visible when reach */ offset_opacity = 1200, /* opacity reduced when reach */ $back_to_top = $('.goto-top'); //hide or show the "back to top" link $(window).scroll(function () { ($(this).scrollTop() > offset) ? $back_to_top.addClass('goto-is-visible'): $back_to_top.removeClass('goto-is-visible goto-fade-out'); if ($(this).scrollTop() > offset_opacity) { $back_to_top.addClass('goto-fade-out'); } }); //smooth scroll to top $back_to_top.on('click', function (event) { event.preventDefault(); $('body,html').animate({ scrollTop: $('#top').offset().top, }, 700); }); })(jQuery); } /* Initialize ScrollReveal.js plugin */ function initialize_scrollreveal() { (function ($) { window.sr = ScrollReveal(); // Add class to if ScrollReveal is supported if (sr.isSupported()) { document.documentElement.classList.add('sr'); } })(jQuery); }