PageSourceSearch

https://springvalleyecofarms.org/wp-content/themes/imedica/js/lib/smooth-scroll.js

js springvalleyecofarms.org collected 2026-09-26 13:10:57 UTC 14,925 bytes, 544 lines download raw bytes

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

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.