Created
June 29, 2017 14:42
-
-
Save surjithctly/87b464ee948908e54bc5ef38a8f88473 to your computer and use it in GitHub Desktop.
Smooth Scroll Plugin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* SmoothScroll for websites v1.2.1. Licensed under the terms of the MIT license. | |
| People involved: Balazs Galambosi (maintainer), Michael Herf (Pulse Algorithm), Edwin Ang (optimzation and added support) */ | |
| (function() { | |
| var defaultOptions = { | |
| frameRate: 150, | |
| animationTime: 750, | |
| stepSize: 120, | |
| pulseAlgorithm: true, | |
| pulseScale: 8, | |
| pulseNormalize: 1, | |
| accelerationDelta: 20, | |
| accelerationMax: 1, | |
| keyboardSupport: true, | |
| arrowScroll: 50, | |
| touchpadSupport: true, | |
| fixedBackground: true, | |
| excluded: "" | |
| }; | |
| var options = defaultOptions; | |
| var isExcluded = false; | |
| var isFrame = false; | |
| var direction = { | |
| x: 0, | |
| y: 0 | |
| }; | |
| var initDone = false; | |
| var root = document.documentElement; | |
| var activeElement; | |
| var observer; | |
| var deltaBuffer = [120, 120, 120]; | |
| var key = { | |
| left: 37, | |
| up: 38, | |
| right: 39, | |
| down: 40, | |
| spacebar: 32, | |
| pageup: 33, | |
| pagedown: 34, | |
| end: 35, | |
| home: 36 | |
| }; | |
| var options = defaultOptions; | |
| function initTest() { | |
| var disableKeyboard = false; | |
| if (disableKeyboard) { | |
| removeEvent("keydown", keydown) | |
| } | |
| ;if (options.keyboardSupport && !disableKeyboard) { | |
| addEvent("keydown", keydown) | |
| } | |
| ; | |
| } | |
| function init() { | |
| if (!document.body) | |
| return; | |
| var e = document.body; | |
| var t = document.documentElement; | |
| var n = window.innerHeight; | |
| var r = e.scrollHeight; | |
| root = document.compatMode.indexOf("CSS") >= 0 ? t : e; | |
| activeElement = e; | |
| initTest(); | |
| initDone = true; | |
| if (top != self) { | |
| isFrame = true | |
| } else if (r > n && (e.offsetHeight <= n || t.offsetHeight <= n)) { | |
| var i = false; | |
| var s = function() { | |
| if (!i && t.scrollHeight != document.height) { | |
| i = true; | |
| setTimeout(function() { | |
| t.style.height = document.height + "px"; | |
| i = false | |
| }, 500) | |
| } | |
| }; | |
| t.style.height = "auto"; | |
| setTimeout(s, 10); | |
| if (root.offsetHeight <= n) { | |
| var o = document.createElement("div"); | |
| o.style.clear = "both"; | |
| e.appendChild(o) | |
| } | |
| } | |
| if (!options.fixedBackground && !isExcluded) { | |
| e.style.backgroundAttachment = "scroll"; | |
| t.style.backgroundAttachment = "scroll" | |
| } | |
| } | |
| function scrollArray(e, t, n, r) { | |
| r || (r = 1e3); | |
| directionCheck(t, n); | |
| if (options.accelerationMax != 1) { | |
| var i = +(new Date); | |
| var s = i - lastScroll; | |
| if (s < options.accelerationDelta) { | |
| var o = (1 + 30 / s) / 2; | |
| if (o > 1) { | |
| o = Math.min(o, options.accelerationMax); | |
| t *= o; | |
| n *= o | |
| } | |
| } | |
| lastScroll = +(new Date) | |
| } | |
| que.push({ | |
| x: t, | |
| y: n, | |
| lastX: t < 0 ? .99 : -.99, | |
| lastY: n < 0 ? .99 : -.99, | |
| start: +(new Date) | |
| }); | |
| if (pending) { | |
| return | |
| } | |
| var u = e === document.body; | |
| var a = function(i) { | |
| var s = +(new Date); | |
| var o = 0; | |
| var f = 0; | |
| for (var l = 0; l < que.length; l++) { | |
| var c = que[l]; | |
| var h = s - c.start; | |
| var p = h >= options.animationTime; | |
| var d = p ? 1 : h / options.animationTime; | |
| if (options.pulseAlgorithm) { | |
| d = pulse(d) | |
| } | |
| var v = c.x * d - c.lastX >> 0; | |
| var m = c.y * d - c.lastY >> 0; | |
| o += v; | |
| f += m; | |
| c.lastX += v; | |
| c.lastY += m; | |
| if (p) { | |
| que.splice(l, 1); | |
| l-- | |
| } | |
| } | |
| if (u) { | |
| window.scrollBy(o, f) | |
| } else { | |
| if (o) | |
| e.scrollLeft += o; | |
| if (f) | |
| e.scrollTop += f | |
| } | |
| if (!t && !n) { | |
| que = [] | |
| } | |
| if (que.length) { | |
| requestFrame(a, e, r / options.frameRate + 1) | |
| } else { | |
| pending = false | |
| } | |
| }; | |
| requestFrame(a, e, 0); | |
| pending = true | |
| } | |
| function wheel(e) { | |
| if (!initDone) { | |
| init() | |
| } | |
| var t = e.target; | |
| var n = overflowingAncestor(t); | |
| if (!n || e.defaultPrevented || isNodeName(activeElement, "embed") || isNodeName(t, "embed") && /\.pdf/i.test(t.src)) { | |
| return true | |
| } | |
| var r = e.wheelDeltaX || 0; | |
| var i = e.wheelDeltaY || 0; | |
| if (!r && !i) { | |
| i = e.wheelDelta || 0 | |
| } | |
| if (!options.touchpadSupport && isTouchpad(i)) { | |
| return true | |
| } | |
| if (Math.abs(r) > 1.2) { | |
| r *= options.stepSize / 120 | |
| } | |
| if (Math.abs(i) > 1.2) { | |
| i *= options.stepSize / 120 | |
| } | |
| scrollArray(n, -r, -i); | |
| e.preventDefault() | |
| } | |
| function keydown(e) { | |
| var t = e.target; | |
| var n = e.ctrlKey || e.altKey || e.metaKey || e.shiftKey && e.keyCode !== key.spacebar; | |
| if (/input|textarea|select|embed/i.test(t.nodeName) || t.isContentEditable || e.defaultPrevented || n) { | |
| return true | |
| } | |
| if (isNodeName(t, "button") && e.keyCode === key.spacebar) { | |
| return true | |
| } | |
| var r, i = 0, s = 0; | |
| var o = overflowingAncestor(activeElement); | |
| var u = o.clientHeight; | |
| if (o == document.body) { | |
| u = window.innerHeight | |
| } | |
| switch (e.keyCode) { | |
| case key.up: | |
| s = -options.arrowScroll; | |
| break; | |
| case key.down: | |
| s = options.arrowScroll; | |
| break; | |
| case key.spacebar: | |
| r = e.shiftKey ? 1 : -1; | |
| s = -r * u * .9; | |
| break; | |
| case key.pageup: | |
| s = -u * .9; | |
| break; | |
| case key.pagedown: | |
| s = u * .9; | |
| break; | |
| case key.home: | |
| s = -o.scrollTop; | |
| break; | |
| case key.end: | |
| var a = o.scrollHeight - o.scrollTop - u; | |
| s = a > 0 ? a + 10 : 0; | |
| break; | |
| case key.left: | |
| i = -options.arrowScroll; | |
| break; | |
| case key.right: | |
| i = options.arrowScroll; | |
| break; | |
| default: | |
| return true | |
| } | |
| scrollArray(o, i, s); | |
| e.preventDefault() | |
| } | |
| var que = []; | |
| var pending = false; | |
| var lastScroll = +(new Date); | |
| function mousedown(e) { | |
| activeElement = e.target | |
| } | |
| function setCache(e, t) { | |
| for (var n = e.length; n--; ) | |
| cache[uniqueID(e[n])] = t; | |
| return t | |
| } | |
| function overflowingAncestor(e) { | |
| var t = []; | |
| var n = root.scrollHeight; | |
| do { | |
| var r = cache[uniqueID(e)]; | |
| if (r) { | |
| return setCache(t, r) | |
| } | |
| t.push(e); | |
| if (n === e.scrollHeight) { | |
| if (!isFrame || root.clientHeight + 10 < n) { | |
| return setCache(t, document.body) | |
| } | |
| } else if (e.clientHeight + 10 < e.scrollHeight) { | |
| overflow = getComputedStyle(e, "").getPropertyValue("overflow-y"); | |
| if (overflow === "scroll" || overflow === "auto") { | |
| return setCache(t, e) | |
| } | |
| } | |
| } while (e = e.parentNode) | |
| } | |
| function addEvent(e, t, n) { | |
| window.addEventListener(e, t, n || false) | |
| } | |
| function removeEvent(e, t, n) { | |
| window.removeEventListener(e, t, n || false) | |
| } | |
| function isNodeName(e, t) { | |
| return (e.nodeName || "").toLowerCase() === t.toLowerCase() | |
| } | |
| function directionCheck(e, t) { | |
| e = e > 0 ? 1 : -1; | |
| t = t > 0 ? 1 : -1; | |
| if (direction.x !== e || direction.y !== t) { | |
| direction.x = e; | |
| direction.y = t; | |
| que = []; | |
| lastScroll = 0 | |
| } | |
| } | |
| function isTouchpad(e) { | |
| if (!e) | |
| return; | |
| e = Math.abs(e); | |
| deltaBuffer.push(e); | |
| deltaBuffer.shift(); | |
| clearTimeout(deltaBufferTimer); | |
| var t = isDivisible(deltaBuffer[0], 120) && isDivisible(deltaBuffer[1], 120) && isDivisible(deltaBuffer[2], 120); | |
| return !t | |
| } | |
| function isDivisible(e, t) { | |
| return Math.floor(e / t) == e / t | |
| } | |
| function pulse_(e) { | |
| var t, n, r; | |
| e = e * options.pulseScale; | |
| if (e < 1) { | |
| t = e - (1 - Math.exp(-e)) | |
| } else { | |
| n = Math.exp(-1); | |
| e -= 1; | |
| r = 1 - Math.exp(-e); | |
| t = n + r * (1 - n) | |
| } | |
| return t * options.pulseNormalize | |
| } | |
| var cache = {}; | |
| setInterval(function() { | |
| cache = {} | |
| }, 10 * 1e3); | |
| var uniqueID = function() { | |
| var e = 0; | |
| return function(t) { | |
| return t.uniqueID || (t.uniqueID = e++) | |
| } | |
| }(); | |
| var deltaBufferTimer; | |
| var requestFrame = function() { | |
| return window.requestAnimationFrame || window.webkitRequestAnimationFrame || function(e, t, n) { | |
| window.setTimeout(e, n || 1e3 / 60) | |
| } | |
| }(); | |
| function pulse(e) { | |
| if (e >= 1) | |
| return 1; | |
| if (e <= 0) | |
| return 0; | |
| if (options.pulseNormalize == 1) { | |
| options.pulseNormalize /= pulse_(1) | |
| } | |
| return pulse_(e) | |
| } | |
| var isSupportedBrowser = /chrome/i.test(window.navigator.userAgent) ? true : /safari/i.test(window.navigator.userAgent); | |
| var wheelEvent = null; | |
| if ("onwheel"in document.createElement("div")) | |
| wheelEvent = "wheel"; | |
| else if ("onmousewheel"in document.createElement("div")) | |
| wheelEvent = "mousewheel"; | |
| if (wheelEvent && isSupportedBrowser) { | |
| addEvent(wheelEvent, wheel); | |
| addEvent("mousedown", mousedown); | |
| addEvent("load", init) | |
| } | |
| })(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* SmoothScroll for websites v1.2.1. Licensed under the terms of the MIT license. People involved: Balazs Galambosi (maintainer), Michael Herf (Pulse Algorithm), Edwin Ang (optimzation and added support) */ (function(){var defaultOptions={frameRate: 150,animationTime: 750,stepSize: 120,pulseAlgorithm: true,pulseScale: 8,pulseNormalize: 1,accelerationDelta: 20,accelerationMax: 1,keyboardSupport: true,arrowScroll: 50,touchpadSupport: true,fixedBackground: true, excluded: ""};var options = defaultOptions;var isExcluded=false;var isFrame=false;var direction={x:0,y:0};var initDone=false;var root=document.documentElement;var activeElement;var observer;var deltaBuffer=[120,120,120];var key={left:37,up:38,right:39,down:40,spacebar:32,pageup:33,pagedown:34,end:35,home:36};var options = defaultOptions;function initTest() {var disableKeyboard = false; if(disableKeyboard){removeEvent("keydown", keydown)}; if (options.keyboardSupport && !disableKeyboard){addEvent("keydown", keydown)};}function init(){if(!document.body)return;var e=document.body;var t=document.documentElement;var n=window.innerHeight;var r=e.scrollHeight;root=document.compatMode.indexOf("CSS")>=0?t:e;activeElement=e;initTest();initDone=true;if(top!=self){isFrame=true}else if(r>n&&(e.offsetHeight<=n||t.offsetHeight<=n)){var i=false;var s=function(){if(!i&&t.scrollHeight!=document.height){i=true;setTimeout(function(){t.style.height=document.height+"px";i=false},500)}};t.style.height="auto";setTimeout(s,10);if(root.offsetHeight<=n){var o=document.createElement("div");o.style.clear="both";e.appendChild(o)}}if(!options.fixedBackground&&!isExcluded){e.style.backgroundAttachment="scroll";t.style.backgroundAttachment="scroll"}}function scrollArray(e,t,n,r){r||(r=1e3);directionCheck(t,n);if(options.accelerationMax!=1){var i=+(new Date);var s=i-lastScroll;if(s<options.accelerationDelta){var o=(1+30/s)/2;if(o>1){o=Math.min(o,options.accelerationMax);t*=o;n*=o}}lastScroll=+(new Date)}que.push({x:t,y:n,lastX:t<0?.99:-.99,lastY:n<0?.99:-.99,start:+(new Date)});if(pending){return}var u=e===document.body;var a=function(i){var s=+(new Date);var o=0;var f=0;for(var l=0;l<que.length;l++){var c=que[l];var h=s-c.start;var p=h>=options.animationTime;var d=p?1:h/options.animationTime;if(options.pulseAlgorithm){d=pulse(d)}var v=c.x*d-c.lastX>>0;var m=c.y*d-c.lastY>>0;o+=v;f+=m;c.lastX+=v;c.lastY+=m;if(p){que.splice(l,1);l--}}if(u){window.scrollBy(o,f)}else{if(o)e.scrollLeft+=o;if(f)e.scrollTop+=f}if(!t&&!n){que=[]}if(que.length){requestFrame(a,e,r/options.frameRate+1)}else{pending=false}};requestFrame(a,e,0);pending=true}function wheel(e){if(!initDone){init()}var t=e.target;var n=overflowingAncestor(t);if(!n||e.defaultPrevented||isNodeName(activeElement,"embed")||isNodeName(t,"embed")&&/\.pdf/i.test(t.src)){return true}var r=e.wheelDeltaX||0;var i=e.wheelDeltaY||0;if(!r&&!i){i=e.wheelDelta||0}if(!options.touchpadSupport&&isTouchpad(i)){return true}if(Math.abs(r)>1.2){r*=options.stepSize/120}if(Math.abs(i)>1.2){i*=options.stepSize/120}scrollArray(n,-r,-i);e.preventDefault()}function keydown(e){var t=e.target;var n=e.ctrlKey||e.altKey||e.metaKey||e.shiftKey&&e.keyCode!==key.spacebar;if(/input|textarea|select|embed/i.test(t.nodeName)||t.isContentEditable||e.defaultPrevented||n){return true}if(isNodeName(t,"button")&&e.keyCode===key.spacebar){return true}var r,i=0,s=0;var o=overflowingAncestor(activeElement);var u=o.clientHeight;if(o==document.body){u=window.innerHeight}switch(e.keyCode){case key.up:s=-options.arrowScroll;break;case key.down:s=options.arrowScroll;break;case key.spacebar:r=e.shiftKey?1:-1;s=-r*u*.9;break;case key.pageup:s=-u*.9;break;case key.pagedown:s=u*.9;break;case key.home:s=-o.scrollTop;break;case key.end:var a=o.scrollHeight-o.scrollTop-u;s=a>0?a+10:0;break;case key.left:i=-options.arrowScroll;break;case key.right:i=options.arrowScroll;break;default:return true}scrollArray(o,i,s);e.preventDefault()}var que=[];var pending=false;var lastScroll=+(new Date);function mousedown(e){activeElement=e.target}function setCache(e,t){for(var n=e.length;n--;)cache[uniqueID(e[n])]=t;return t}function overflowingAncestor(e){var t=[];var n=root.scrollHeight;do{var r=cache[uniqueID(e)];if(r){return setCache(t,r)}t.push(e);if(n===e.scrollHeight){if(!isFrame||root.clientHeight+10<n){return setCache(t,document.body)}}else if(e.clientHeight+10<e.scrollHeight){overflow=getComputedStyle(e,"").getPropertyValue("overflow-y");if(overflow==="scroll"||overflow==="auto"){return setCache(t,e)}}}while(e=e.parentNode)}function addEvent(e,t,n){window.addEventListener(e,t,n||false)}function removeEvent(e,t,n){window.removeEventListener(e,t,n||false)}function isNodeName(e,t){return(e.nodeName||"").toLowerCase()===t.toLowerCase()}function directionCheck(e,t){e=e>0?1:-1;t=t>0?1:-1;if(direction.x!==e||direction.y!==t){direction.x=e;direction.y=t;que=[];lastScroll=0}}function isTouchpad(e){if(!e)return;e=Math.abs(e);deltaBuffer.push(e);deltaBuffer.shift();clearTimeout(deltaBufferTimer);var t=isDivisible(deltaBuffer[0],120)&&isDivisible(deltaBuffer[1],120)&&isDivisible(deltaBuffer[2],120);return!t}function isDivisible(e,t){return Math.floor(e/t)==e/t}function pulse_(e){var t,n,r;e=e*options.pulseScale;if(e<1){t=e-(1-Math.exp(-e))}else{n=Math.exp(-1);e-=1;r=1-Math.exp(-e);t=n+r*(1-n)}return t*options.pulseNormalize}var cache={};setInterval(function(){cache={}},10*1e3);var uniqueID=function(){var e=0;return function(t){return t.uniqueID||(t.uniqueID=e++)}}();var deltaBufferTimer;var requestFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||function(e,t,n){window.setTimeout(e,n||1e3/60)}}();function pulse(e){if(e>=1)return 1;if(e<=0)return 0;if(options.pulseNormalize==1){options.pulseNormalize/=pulse_(1)}return pulse_(e)}var isSupportedBrowser=/chrome/i.test(window.navigator.userAgent)?true:/safari/i.test(window.navigator.userAgent);var wheelEvent=null;if("onwheel"in document.createElement("div"))wheelEvent="wheel";else if("onmousewheel"in document.createElement("div"))wheelEvent="mousewheel";if(wheelEvent&&isSupportedBrowser){addEvent(wheelEvent,wheel);addEvent("mousedown",mousedown);addEvent("load",init)}})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment