PageSourceSearch

https://hoster.kg/wp-content/themes/arkahost/assets/js/smoothscroll.js?ver=5.1.2

js hoster.kg collected 2026-10-09 23:37:10 UTC 13,950 bytes, 530 lines download raw bytes

1// SmoothScroll for websites v1.2.1
2// Licensed under the terms of the MIT license.
3
4// People involved
5//  - Balazs Galambosi (maintainer)  
6//  - Michael Herf     (Pulse Algorithm)
7
8(function($) {
9 "use strict";
10
11(function(){
12  
13// Scroll Variables (tweakable)
14var defaultOptions = {
15
16    // Scrolling Core
17    frameRate        : 150, // [Hz]
18    animationTime    : 1800, // [px]
19    stepSize         : 85, // [px]
20
21    // Pulse (less tweakable)
22    // ratio of "tail" to "acceleration"
23    pulseAlgorithm   : true,
24    pulseScale       : 8,
25    pulseNormalize   : 1,
26
27    // Acceleration
28    accelerationDelta : 20,  // 20
29    accelerationMax   : 1,   // 1
30
31    // Keyboard Settings
32    keyboardSupport   : true,  // option
33    arrowScroll       : 50,     // [px]
34
35    // Other
36    touchpadSupport   : true,
37    fixedBackground   : true, 
38    excluded          : ""    
39};
40
41var options = defaultOptions;
42
43
44// Other Variables
45var isExcluded = false;
46var isFrame = false;
47var direction = { x: 0, y: 0 };
48var initDone  = false;
49var root = document.documentElement;
50var activeElement;
51var observer;
52var deltaBuffer = [ 120, 120, 120 ];
53
54var key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32, 
55            pageup: 33, pagedown: 34, end: 35, home: 36 };
56
57
58/***********************************************
59 * SETTINGS
60 ***********************************************/
61
62var options = defaultOptions;
63
64
65/***********************************************
66 * INITIALIZE
67 ***********************************************/
68
69/**
70 * Tests if smooth scrolling is allowed. Shuts down everything if not.
71 */
72function initTest() {
73
74    var disableKeyboard = false; 
75    
76    // disable keyboard support if anything above requested it
77    if (disableKeyboard) {
78        removeEvent("keydown", keydown);
79    }
80
81    if (options.keyboardSupport && !disableKeyboard) {
82        addEvent("keydown", keydown);
83    }
84}
85
86/**
87 * Sets up scrolls array, determines if frames are involved.
88 */
89function init() {
90  
91    if (!document.body) return;
92
93    var body = document.body;
94    var html = document.documentElement;
95    var windowHeight = window.innerHeight; 
96    var scrollHeight = body.scrollHeight;
97    
98    // check compat mode for root element
99    root = (document.compatMode.indexOf('CSS') >= 0) ? html : body;
100    activeElement = body;
101    
102    initTest();
103    initDone = true;
104
105    // Checks if this script is running in a frame
106    if (top != self) {
107        isFrame = true;
108    }
109
110    /**
111     * This fixes a bug where the areas left and right to 
112     * the content does not trigger the onmousewheel event
113     * on some pages. e.g.: html, body { height: 100% }
114     */
115    else if (scrollHeight > windowHeight &&
116            (body.offsetHeight <= windowHeight || 
117             html.offsetHeight <= windowHeight)) {
118
119        html.style.height = 'auto';
120        //setTimeout(refresh, 10);
121
122        // clearfix
123        if (root.offsetHeight <= windowHeight) {
124            var underlay = document.createElement("div"); 	
125            underlay.style.clear = "both";
126            body.appendChild(underlay);
127        }
128    }
129
130    // disable fixed background
131    if (!options.fixedBackground && !isExcluded) {
132        body.style.backgroundAttachment = "scroll";
133        html.style.backgroundAttachment = "scroll";
134    }
135}
136
137
138/************************************************
139 * SCROLLING 
140 ************************************************/
141 
142var que = [];
143var pending = false;
144var lastScroll = +new Date;
145
146/**
147 * Pushes scroll actions to the scrolling queue.
148 */
149function scrollArray(elem, left, top, delay) {
150    
151    delay || (delay = 1000);
152    directionCheck(left, top);
153
154    if (options.accelerationMax != 1) {
155        var now = +new Date;
156        var elapsed = now - lastScroll;
157        if (elapsed < options.accelerationDelta) {
158            var factor = (1 + (30 / elapsed)) / 2;
159            if (factor > 1) {
160                factor = Math.min(factor, options.accelerationMax);
161                left *= factor;
162                top  *= factor;
163            }
164        }
165        lastScroll = +new Date;
166    }          
167    
168    // push a scroll command
169    que.push({
170        x: left, 
171        y: top, 
172        lastX: (left < 0) ? 0.99 : -0.99,
173        lastY: (top  < 0) ? 0.99 : -0.99, 
174        start: +new Date
175    });
176        
177    // don't act if there's a pending queue
178    if (pending) {
179        return;
180    }  
181
182    var scrollWindow = (elem === document.body);
183    
184    var step = function (time) {
185        
186        var now = +new Date;
187        var scrollX = 0;
188        var scrollY = 0; 
189    
190        for (var i = 0; i < que.length; i++) {
191            
192            var item = que[i];
193            var elapsed  = now - item.start;
194            var finished = (elapsed >= options.animationTime);
195            
196            // scroll position: [0, 1]
197            var position = (finished) ? 1 : elapsed / options.animationTime;
198            
199            // easing [optional]
200            if (options.pulseAlgorithm) {
201                position = pulse(position);
202            }
203            
204            // only need the difference
205            var x = (item.x * position - item.lastX) >> 0;
206            var y = (item.y * position - item.lastY) >> 0;
207            
208            // add this to the total scrolling
209            scrollX += x;
210            scrollY += y;            
211            
212            // update last values
213            item.lastX += x;
214            item.lastY += y;
215        
216            // delete and step back if it's over
217            if (finished) {
218                que.splice(i, 1); i--;
219            }           
220        }
221
222        // scroll left and top
223        if (scrollWindow) {
224            window.scrollBy(scrollX, scrollY);
225        } 
226        else {
227            if (scrollX) elem.scrollLeft += scrollX;
228            if (scrollY) elem.scrollTop  += scrollY;                    
229        }
230        
231        // clean up if there's nothing left to do
232        if (!left && !top) {
233            que = [];
234        }
235        
236        if (que.length) { 
237            requestFrame(step, elem, (delay / options.frameRate + 1)); 
238        } else { 
239            pending = false;
240        }
241    };
242    
243    // start a new queue of actions
244    requestFrame(step, elem, 0);
245    pending = true;
246}
247
248
249/***********************************************
250 * EVENTS
251 ***********************************************/
252
253/**
254 * Mouse wheel handler.
255 * @param {Object} event
256 */
257function wheel(event) {
258
259    if (!initDone) {
260        init();
261    }
262    
263    var target = event.target;
264    var overflowing = overflowingAncestor(target);
265    
266    // use default if there's no overflowing
267    // element or default action is prevented    
268    if (!overflowing || event.defaultPrevented ||
269        isNodeName(activeElement, "embed") ||
270       (isNodeName(target, "embed") && /\.pdf/i.test(target.src))) {
271        return true;
272    }
273
274    var deltaX = event.wheelDeltaX || 0;
275    var deltaY = event.wheelDeltaY || 0;
276    
277    // use wheelDelta if deltaX/Y is not available
278    if (!deltaX && !deltaY) {
279        deltaY = event.wheelDelta || 0;
280    }
281
282    // check if it's a touchpad scroll that should be ignored
283    if (!options.touchpadSupport && isTouchpad(deltaY)) {
284        return true;
285    }
286
287    // scale by step size
288    // delta is 120 most of the time
289    // synaptics seems to send 1 sometimes
290    if (Math.abs(deltaX) > 1.2) {
291        deltaX *= options.stepSize / 120;
292    }
293    if (Math.abs(deltaY) > 1.2) {
294        deltaY *= options.stepSize / 120;
295    }
296    
297    scrollArray(overflowing, -deltaX, -deltaY);
298    event.preventDefault();
299}
300
301/**
302 * Keydown event handler.
303 * @param {Object} event
304 */
305function keydown(event) {
306
307    var target   = event.target;
308    var modifier = event.ctrlKey || event.altKey || event.metaKey || 
309                  (event.shiftKey && event.keyCode !== key.spacebar);
310    
311    // do nothing if user is editing text
312    // or using a modifier key (except shift)
313    // or in a dropdown
314    if ( /input|textarea|select|embed/i.test(target.nodeName) ||
315         target.isContentEditable || 
316         event.defaultPrevented   ||
317         modifier ) {
318      return true;
319    }
320    // spacebar should trigger button press
321    if (isNodeName(target, "button") &&
322        event.keyCode === key.spacebar) {
323      return true;
324    }
325    
326    var shift, x = 0, y = 0;
327    var elem = overflowingAncestor(activeElement);
328    var clientHeight = elem.clientHeight;
329
330    if (elem == document.body) {
331        clientHeight = window.innerHeight;
332    }
333
334    switch (event.keyCode) {
335        case key.up:
336            y = -options.arrowScroll;
337            break;
338        case key.down:
339            y = options.arrowScroll;
340            break;         
341        case key.spacebar: // (+ shift)
342            shift = event.shiftKey ? 1 : -1;
343            y = -shift * clientHeight * 0.9;
344            break;
345        case key.pageup:
346            y = -clientHeight * 0.9;
347            break;
348        case key.pagedown:
349            y = clientHeight * 0.9;
350            break;
351        case key.home:
352            y = -elem.scrollTop;
353            break;
354        case key.end:
355            var damt = elem.scrollHeight - elem.scrollTop - clientHeight;
356            y = (damt > 0) ? damt+10 : 0;
357            break;
358        case key.left:
359            x = -options.arrowScroll;
360            break;
361        case key.right:
362            x = options.arrowScroll;
363            break;            
364        default:
365            return true; // a key we don't care about
366    }
367
368    scrollArray(elem, x, y);
369    event.preventDefault();
370}
371
372/**
373 * Mousedown event only for updating activeElement
374 */
375function mousedown(event) {
376    activeElement = event.target;
377}
378
379
380/***********************************************
381 * OVERFLOW
382 ***********************************************/
383 
384var cache = {}; // cleared out every once in while
385setInterval(function () { cache = {}; }, 10 * 1000);
386
387var uniqueID = (function () {
388    var i = 0;
389    return function (el) {
390        return el.uniqueID || (el.uniqueID = i++);
391    };
392})();
393
394function setCache(elems, overflowing) {
395    for (var i = elems.length; i--;)
396        cache[uniqueID(elems[i])] = overflowing;
397    return overflowing;
398}
399
400function overflowingAncestor(el) {
401    var elems = [], overflow = null;
402    var rootScrollHeight = root.scrollHeight;
403    do {
404        var cached = cache[uniqueID(el)];
405        if (cached) {
406            return setCache(elems, cached);
407        }
408        elems.push(el);
409        if (rootScrollHeight === el.scrollHeight) {
410            if (!isFrame || root.clientHeight + 10 < rootScrollHeight) {
411                return setCache(elems, document.body); // scrolling root in WebKit
412            }
413        } else if (el.clientHeight + 10 < el.scrollHeight) {
414            if( getComputedStyle(el, "").getPropertyValue("overflow-y") ){
415            	overflow = getComputedStyle(el, "").getPropertyValue("overflow-y")
416	            if (overflow === "scroll" || overflow === "auto") {
417	                return setCache(elems, el);
418	            }
419	        }   
420        }
421    } while (el = el.parentNode);
422}
423
424
425/***********************************************
426 * HELPERS
427 ***********************************************/
428
429function addEvent(type, fn, bubble) {
430    window.addEventListener(type, fn, (bubble||false));
431}
432
433function removeEvent(type, fn, bubble) {
434    window.removeEventListener(type, fn, (bubble||false));  
435}
436
437function isNodeName(el, tag) {
438    return (el.nodeName||"").toLowerCase() === tag.toLowerCase();
439}
440
441function directionCheck(x, y) {
442    x = (x > 0) ? 1 : -1;
443    y = (y > 0) ? 1 : -1;
444    if (direction.x !== x || direction.y !== y) {
445        direction.x = x;
446        direction.y = y;
447        que = [];
448        lastScroll = 0;
449    }
450}
451
452var deltaBufferTimer;
453
454function isTouchpad(deltaY) {
455    if (!deltaY) return;
456    deltaY = Math.abs(deltaY)
457    deltaBuffer.push(deltaY);
458    deltaBuffer.shift();
459    clearTimeout(deltaBufferTimer);
460
461    var allEquals    = (deltaBuffer[0] == deltaBuffer[1] && 
462                        deltaBuffer[1] == deltaBuffer[2]);
463    var allDivisable = (isDivisible(deltaBuffer[0], 120) &&
464                        isDivisible(deltaBuffer[1], 120) &&
465                        isDivisible(deltaBuffer[2], 120));
466    return !(allEquals || allDivisable);
467} 
468
469function isDivisible(n, divisor) {
470    return (Math.floor(n / divisor) == n / divisor);
471}
472
473var requestFrame = (function () {
474      return  window.requestAnimationFrame       || 
475              window.webkitRequestAnimationFrame || 
476              function (callback, element, delay) {
477                  window.setTimeout(callback, delay || (1000/60));
478              };
479})();
480
481
482/***********************************************
483 * PULSE
484 ***********************************************/
485 
486/**
487 * Viscous fluid with a pulse for part and decay for the rest.
488 * - Applies a fixed force over an interval (a damped acceleration), and
489 * - Lets the exponential bleed away the velocity over a longer interval
490 * - Michael Herf, http://stereopsis.com/stopping/
491 */
492function pulse_(x) {
493    var val, start, expx;
494    // test
495    x = x * options.pulseScale;
496    if (x < 1) { // acceleartion
497        val = x - (1 - Math.exp(-x));
498    } else {     // tail
499        // the previous animation ended here:
500        start = Math.exp(-1);
501        // simple viscous drag
502        x -= 1;
503        expx = 1 - Math.exp(-x);
504        val = start + (expx * (1 - start));
505    }
506    return val * options.pulseNormalize;
507}
508
509function pulse(x) {
510    if (x >= 1) return 1;
511    if (x <= 0) return 0;
512
513    if (options.pulseNormalize == 1) {
514        options.pulseNormalize /= pulse_(1);
515    }
516    return pulse_(x);
517}
518
519var isChrome = /chrome/i.test(window.navigator.userAgent);
520var isMouseWheelSupported = 'onmousewheel' in document; 
521
522if (isMouseWheelSupported && isChrome) {
523	addEvent("mousedown", mousedown);
524	addEvent("mousewheel", wheel);
525	addEvent("load", init);
526};
527
528})();
529
530})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.