(function($) { "use strict"; (function() { var defaultoptions = { framerate: 150, animationtime: 1800, stepsize: 85, 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 body = document.body; var html = document.documentelement; var windowheight = window.innerheight; var scrollheight = body.scrollheight; root = (document.compatmode.indexof('css') >= 0) ? html : body; activeelement = body; inittest(); initdone = true; if (top != self) { isframe = true } else if (scrollheight > windowheight && (body.offsetheight <= windowheight || html.offsetheight <= windowheight)) { html.style.height = 'auto'; if (root.offsetheight <= windowheight) { var underlay = document.createelement("div"); underlay.style.clear = "both"; body.appendchild(underlay) } } if (!options.fixedbackground && !isexcluded) { body.style.backgroundattachment = "scroll"; html.style.backgroundattachment = "scroll" } } var que = []; var pending = false; var lastscroll = +new date; function scrollarray(elem, left, top, delay) { delay || (delay = 1000); directioncheck(left, top); if (options.accelerationmax != 1) { var now = +new date; var elapsed = now - lastscroll; if (elapsed < options.accelerationdelta) { var factor = (1 + (30 / elapsed)) / 2; if (factor > 1) { factor = math.min(factor, options.accelerationmax); left *= factor; top *= factor } } lastscroll = +new date } que.push({ x: left, y: top, lastx: (left < 0) ? 0.99 : -0.99, lasty: (top < 0) ? 0.99 : -0.99, start: +new date }); if (pending) { return } var scrollwindow = (elem === document.body); var step = function(time) { var now = +new date; 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); var position = (finished) ? 1 : elapsed / options.animationtime; if (options.pulsealgorithm) { position = pulse(position) } var x = (item.x * position - item.lastx) >> 0; var y = (item.y * position - item.lasty) >> 0; scrollx += x; scrolly += y; item.lastx += x; item.lasty += y; if (finished) { que.splice(i, 1); i-- } } if (scrollwindow) { window.scrollby(scrollx, scrolly) } else { if (scrollx) elem.scrollleft += scrollx; if (scrolly) elem.scrolltop += scrolly } if (!left && !top) { que = [] } if (que.length) { requestframe(step, elem, (delay / options.framerate + 1)) } else { pending = false } }; requestframe(step, elem, 0); pending = true } function wheel(event) { if (!initdone) { init() } var target = event.target; var overflowing = overflowingancestor(target); if (!overflowing || event.defaultprevented || isnodename(activeelement, "embed") || (isnodename(target, "embed") && /\.pdf/i.test(target.src))) { return true } var deltax = event.wheeldeltax || 0; var deltay = event.wheeldeltay || 0; if (!deltax && !deltay) { deltay = event.wheeldelta || 0 } if (!options.touchpadsupport && istouchpad(deltay)) { return true } 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() } function keydown(event) { var target = event.target; var modifier = event.ctrlkey || event.altkey || event.metakey || (event.shiftkey && event.keycode !== key.spacebar); if (/input|textarea|select|embed/i.test(target.nodename) || target.iscontenteditable || event.defaultprevented || modifier) { return true } if (isnodename(target, "button") && 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 = 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 } scrollarray(elem, x, y); event.preventdefault() } function mousedown(event) { activeelement = event.target } var cache = {}; setinterval(function() { cache = {} }, 10 * 1000); var uniqueid = (function() { var i = 0; return function(el) { return el.uniqueid || (el.uniqueid = i++) } })(); function setcache(elems, overflowing) { for (var i = elems.length; i--;) cache[uniqueid(elems[i])] = overflowing; return overflowing } function overflowingancestor(el) { var elems = [], overflow = null; var rootscrollheight = root.scrollheight; do { var cached = cache[uniqueid(el)]; if (cached) { return setcache(elems, cached) } elems.push(el); if (rootscrollheight === el.scrollheight) { if (!isframe || root.clientheight + 10 < rootscrollheight) { return setcache(elems, document.body) } } else if (el.clientheight + 10 < el.scrollheight) { if (getcomputedstyle(el, "").getpropertyvalue("overflow-y")) { overflow = getcomputedstyle(el, "").getpropertyvalue("overflow-y"); if (overflow === "scroll" || overflow === "auto") { return setcache(elems, el) } } } } while (el = el.parentnode) } function addevent(type, fn, bubble) { window.addeventlistener(type, fn, (bubble || false)) } function removeevent(type, fn, bubble) { window.removeeventlistener(type, fn, (bubble || 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; function istouchpad(deltay) { if (!deltay) return; deltay = math.abs(deltay); deltabuffer.push(deltay); deltabuffer.shift(); cleartimeout(deltabuffertimer); var allequals = (deltabuffer[0] == deltabuffer[1] && deltabuffer[1] == deltabuffer[2]); var alldivisable = (isdivisible(deltabuffer[0], 120) && isdivisible(deltabuffer[1], 120) && isdivisible(deltabuffer[2], 120)); return !(allequals || alldivisable) } function isdivisible(n, divisor) { return (math.floor(n / divisor) == n / divisor) } var requestframe = (function() { return window.requestanimationframe || window.webkitrequestanimationframe || function(callback, element, delay) { window.settimeout(callback, delay || (1000 / 60)) } })(); function pulse_(x) { var val, start, expx; x = x * options.pulsescale; if (x < 1) { val = x - (1 - math.exp(-x)) } else { start = math.exp(-1); 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) } var ischrome = /chrome/i.test(window.navigator.useragent); var ismousewheelsupported = 'onmousewheel' in document; if (ismousewheelsupported && ischrome) { addevent("mousedown", mousedown); addevent("mousewheel", wheel); addevent("load", init) } })() })(jquery);