PageSourceSearch

https://www.fratellibonacchi.it/wp-content/themes/soprano-ecommerc…/scripts/assets/jarallax.js?ver=6.1.15

js fratellibonacchi.it collected 2026-10-08 12:39:29 UTC 24,862 bytes, 695 lines download raw bytes

1/*!
2 * Name    : Just Another Parallax [Jarallax]
3 * Version : 1.8.0
4 * Author  : _nK https://nkdev.info
5 * GitHub  : https://github.com/nk-o/jarallax
6 */
7(function (window) {
8    'use strict';
9
10    // Adapted from https://gist.github.com/paulirish/1579671
11    if(!Date.now) {
12        Date.now = function () { return new Date().getTime(); };
13    }
14    if(!window.requestAnimationFrame) {
15        (function () {
16
17            var vendors = ['webkit', 'moz'];
18            for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
19                var vp = vendors[i];
20                window.requestAnimationFrame = window[vp+'RequestAnimationFrame'];
21                window.cancelAnimationFrame = window[vp+'CancelAnimationFrame']
22                    || window[vp+'CancelRequestAnimationFrame'];
23            }
24            if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy
25                || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
26                var lastTime = 0;
27                window.requestAnimationFrame = function (callback) {
28                    var now = Date.now();
29                    var nextTime = Math.max(lastTime + 16, now);
30                    return setTimeout(function () { callback(lastTime = nextTime); },
31                        nextTime - now);
32                };
33                window.cancelAnimationFrame = clearTimeout;
34            }
35        }());
36    }
37
38    // test if css property supported by browser
39    // like "transform"
40    var tempDiv = document.createElement('div');
41    function isPropertySupported (property) {
42        var prefixes = ['O','Moz','ms','Ms','Webkit'];
43        var i = prefixes.length;
44        if (tempDiv.style[property] !== undefined) {
45            return true;
46        }
47        property = property.charAt(0).toUpperCase() + property.substr(1);
48        while (--i > -1 && tempDiv.style[prefixes[i] + property] === undefined) { }
49        return i >= 0;
50    }
51
52    var supportTransform = isPropertySupported('transform');
53    var supportTransform3D = isPropertySupported('perspective');
54
55    var ua = navigator.userAgent;
56    var isAndroid = ua.toLowerCase().indexOf('android') > -1;
57    var isIOs = /iPad|iPhone|iPod/.test(ua) && !window.MSStream;
58    var isFirefox = ua.toLowerCase().indexOf('firefox') > -1;
59    var isIE = ua.indexOf('MSIE ') > -1    // IE 10 or older
60        || ua.indexOf('Trident/') > -1 // IE 11
61        || ua.indexOf('Edge/') > -1;   // Edge
62    var isIElt10 = document.all && !window.atob; // IE 9 or older
63
64    var wndW;
65    var wndH;
66    function updateWndVars () {
67        wndW = window.innerWidth || document.documentElement.clientWidth;
68        wndH = window.innerHeight || document.documentElement.clientHeight;
69    }
70    updateWndVars();
71
72    // list with all jarallax instances
73    // need to render all in one scroll/resize event
74    var jarallaxList = [];
75
76    // Jarallax instance
77    var Jarallax = (function () {
78        var instanceID = 0;
79
80        function Jarallax_inner (item, userOptions) {
81            var _this = this,
82                dataOptions;
83
84            _this.$item      = item;
85
86            _this.defaults   = {
87                type              : 'scroll', // type of parallax: scroll, scale, opacity, scale-opacity, scroll-opacity
88                speed             : 0.5, // supported value from -1 to 2
89                imgSrc            : null,
90                imgWidth          : null,
91                imgHeight         : null,
92                elementInViewport : null,
93                zIndex            : -100,
94                noAndroid         : false,
95                noIos             : true,
96
97                // events
98                onScroll          : null, // function(calculations) {}
99                onInit            : null, // function() {}
100                onDestroy         : null, // function() {}
101                onCoverImage      : null  // function() {}
102            };
103            dataOptions      = JSON.parse(_this.$item.getAttribute('data-jarallax') || '{}');
104            _this.options    = _this.extend({}, _this.defaults, dataOptions, userOptions);
105
106            // stop init if android or ios
107            if(!supportTransform || isAndroid && _this.options.noAndroid || isIOs && _this.options.noIos) {
108                return;
109            }
110
111            // fix speed option [-1.0, 2.0]
112            _this.options.speed = Math.min(2, Math.max(-1, parseFloat(_this.options.speed)));
113
114            // custom element to check if parallax in viewport
115            var elementInVP = _this.options.elementInViewport;
116            // get first item from array
117            if(elementInVP && typeof elementInVP === 'object' && typeof elementInVP.length !== 'undefined') {
118                elementInVP = elementInVP[0];
119            }
120            // check if dom element
121            if(!elementInVP instanceof Element) {
122                elementInVP = null;
123            }
124            _this.options.elementInViewport = elementInVP;
125
126            _this.instanceID = instanceID++;
127
128            _this.image      = {
129                src        : _this.options.imgSrc || null,
130                $container : null,
131                $item      : null,
132                width      : _this.options.imgWidth || null,
133                height     : _this.options.imgHeight || null,
134                // fix for some devices
135                // use <img> instead of background image - more smoothly
136                useImgTag  : isIOs || isAndroid || isIE,
137
138                // position absolute is needed on IE9 and FireFox because fixed position have glitches
139                position   : !supportTransform3D || isFirefox ? 'absolute' : 'fixed'
140            };
141
142            if(_this.initImg()) {
143                _this.init();
144            }
145        }
146
147        return Jarallax_inner;
148    }());
149
150    // add styles to element
151    Jarallax.prototype.css = function (el, styles) {
152        if(typeof styles === 'string') {
153            if(window.getComputedStyle) {
154                return window.getComputedStyle(el).getPropertyValue(styles);
155            }
156            return el.style[styles];
157        }
158
159        // add transform property with vendor prefixes
160        if(styles.transform) {
161            if (supportTransform3D) {
162                styles.transform += ' translateZ(0)';
163            }
164            styles.WebkitTransform = styles.MozTransform = styles.msTransform = styles.OTransform = styles.transform;
165        }
166
167        for(var k in styles) {
168            el.style[k] = styles[k];
169        }
170        return el;
171    };
172    // Extend like jQuery.extend
173    Jarallax.prototype.extend = function (out) {
174        out = out || {};
175        for (var i = 1; i < arguments.length; i++) {
176            if (!arguments[i]) {
177                continue;
178            }
179            for (var key in arguments[i]) {
180                if (arguments[i].hasOwnProperty(key)) {
181                    out[key] = arguments[i][key];
182                }
183            }
184        }
185        return out;
186    };
187
188    // Jarallax functions
189    Jarallax.prototype.initImg = function () {
190        var _this = this;
191
192        // get image src
193        if(_this.image.src === null) {
194            _this.image.src = _this.css(_this.$item, 'background-image').replace(/^url\(['"]?/g,'').replace(/['"]?\)$/g,'');
195        }
196        return !(!_this.image.src || _this.image.src === 'none');
197    };
198
199    Jarallax.prototype.init = function () {
200        var _this = this,
201            containerStyles = {
202                position         : 'absolute',
203                top              : 0,
204                left             : 0,
205                width            : '100%',
206                height           : '100%',
207                overflow         : 'hidden',
208                pointerEvents    : 'none'
209            },
210            imageStyles = {};
211
212        // save default user styles
213        _this.$item.setAttribute('data-jarallax-original-styles', _this.$item.getAttribute('style'));
214
215        // set relative position and z-index to the parent
216        if (_this.css(_this.$item, 'position') === 'static') {
217            _this.css(_this.$item, {
218                position: 'relative'
219            });
220        }
221        if (_this.css(_this.$item, 'z-index') === 'auto') {
222            _this.css(_this.$item, {
223                zIndex: 0
224            });
225        }
226
227        // container for parallax image
228        _this.image.$container = document.createElement('div');
229        _this.css(_this.image.$container, containerStyles);
230        _this.css(_this.image.$container, {
231            visibility : 'hidden',
232            'z-index'  : _this.options.zIndex
233        });
234        _this.image.$container.setAttribute('id', 'jarallax-container-' + _this.instanceID);
235        _this.$item.appendChild(_this.image.$container);
236
237        // use img tag
238        if(_this.image.useImgTag) {
239            _this.image.$item = document.createElement('img');
240            _this.image.$item.setAttribute('src', _this.image.src);
241            imageStyles = _this.extend({
242                'max-width' : 'none'
243            }, containerStyles, imageStyles);
244        }
245
246        // use div with background image
247        else {
248            _this.image.$item = document.createElement('div');
249            imageStyles = _this.extend({
250                'background-position' : '50% 50%',
251                'background-size'     : '100% auto',
252                'background-repeat'   : 'no-repeat no-repeat',
253                'background-image'    : 'url("' + _this.image.src + '")'
254            }, containerStyles, imageStyles);
255        }
256
257        // check if one of parents have transform style (without this check, scroll transform will be inverted)
258        // discussion - https://github.com/nk-o/jarallax/issues/9
259        var parentWithTransform = 0;
260        var $itemParents = _this.$item;
261        while ($itemParents !== null && $itemParents !== document && parentWithTransform === 0) {
262            var parent_transform = _this.css($itemParents, '-webkit-transform') || _this.css($itemParents, '-moz-transform') || _this.css($itemParents, 'transform');
263            if(parent_transform && parent_transform !== 'none') {
264                parentWithTransform = 1;
265
266                // add transform on parallax container if there is parent with transform
267                _this.css(_this.image.$container, {
268                    transform: 'translateX(0) translateY(0)'
269                });
270            }
271            $itemParents = $itemParents.parentNode;
272        }
273
274        // absolute position if one of parents have transformations or parallax without scroll
275        if (parentWithTransform || _this.options.type === 'opacity'|| _this.options.type === 'scale' || _this.options.type === 'scale-opacity') {
276            _this.image.position = 'absolute';
277        }
278
279        // add position to parallax block
280        imageStyles.position = _this.image.position;
281
282        // parallax image
283        _this.css(_this.image.$item, imageStyles);
284        _this.image.$container.appendChild(_this.image.$item);
285
286        // cover image if width and height is ready
287        function initAfterReady () {
288            _this.coverImage();
289            _this.clipContainer();
290            _this.onScroll(true);
291
292            // call onInit event
293            if(_this.options.onInit) {
294                _this.options.onInit.call(_this);
295            }
296
297            // timeout to fix IE blinking
298            setTimeout(function () {
299                if(_this.$item) {
300                    // remove default user background
301                    _this.css(_this.$item, {
302                        'background-image'      : 'none',
303                        'background-attachment' : 'scroll',
304                        'background-size'       : 'auto'
305                    });
306                }
307            }, 0);
308        }
309
310        if(_this.image.width && _this.image.height) {
311            // init if width and height already exists
312            initAfterReady();
313        } else {
314            // load image and get width and height
315            _this.getImageSize(_this.image.src, function (width, height) {
316                _this.image.width  = width;
317                _this.image.height = height;
318                initAfterReady();
319            });
320        }
321
322        jarallaxList.push(_this);
323    };
324
325    Jarallax.prototype.destroy = function () {
326        var _this = this;
327
328        // remove from instances list
329        for(var k = 0, len = jarallaxList.length; k < len; k++) {
330            if(jarallaxList[k].instanceID === _this.instanceID) {
331                jarallaxList.splice(k, 1);
332                break;
333            }
334        }
335
336        // return styles on container as before jarallax init
337        var originalStylesTag = _this.$item.getAttribute('data-jarallax-original-styles');
338        _this.$item.removeAttribute('data-jarallax-original-styles');
339        // null occurs if there is no style tag before jarallax init
340        if(originalStylesTag === 'null') {
341            _this.$item.removeAttribute('style');
342        } else {
343            _this.$item.setAttribute('style', originalStylesTag);
344        }
345
346        // remove additional dom elements
347        if(_this.$clipStyles) {
348            _this.$clipStyles.parentNode.removeChild(_this.$clipStyles);
349        }
350        _this.image.$container.parentNode.removeChild(_this.image.$container);
351
352        // call onDestroy event
353        if(_this.options.onDestroy) {
354            _this.options.onDestroy.call(_this);
355        }
356
357        // delete jarallax from item
358        delete _this.$item.jarallax;
359
360        // delete all variables
361        for(var n in _this) {
362            delete _this[n];
363        }
364    };
365
366    Jarallax.prototype.getImageSize = function (src, callback) {
367        if(!src || !callback) {
368            return;
369        }
370
371        var tempImg = new Image();
372        tempImg.onload = function () {
373            callback(tempImg.width, tempImg.height);
374        };
375        tempImg.src = src;
376    };
377
378    // it will remove some image overlapping
379    // overlapping occur due to an image position fixed inside absolute position element (webkit based browsers works without any fix)
380    Jarallax.prototype.clipContainer = function () {
381        // clip is not working properly on real IE9 and less
382        if(isIElt10) {
383            return;
384        }
385
386        var _this  = this,
387            rect   = _this.image.$container.getBoundingClientRect(),
388            width  = rect.width,
389            height = rect.height;
390
391        if(!_this.$clipStyles) {
392            _this.$clipStyles = document.createElement('style');
393            _this.$clipStyles.setAttribute('type', 'text/css');
394            _this.$clipStyles.setAttribute('id', '#jarallax-clip-' + _this.instanceID);
395            var head = document.head || document.getElementsByTagName('head')[0];
396            head.appendChild(_this.$clipStyles);
397        }
398
399        var styles = [
400            '#jarallax-container-' + _this.instanceID + ' {',
401            '   clip: rect(0 ' + width + 'px ' + height + 'px 0);',
402            '   clip: rect(0, ' + width + 'px, ' + height + 'px, 0);',
403            '}'
404        ].join('\n');
405
406        // add clip styles inline (this method need for support IE8 and less browsers)
407        if (_this.$clipStyles.styleSheet){
408            _this.$clipStyles.styleSheet.cssText = styles;
409        } else {
410            _this.$clipStyles.innerHTML = styles;
411        }
412    };
413
414    Jarallax.prototype.coverImage = function () {
415        var _this = this;
416
417        if(!_this.image.width || !_this.image.height) {
418            return;
419        }
420
421        var rect       = _this.image.$container.getBoundingClientRect(),
422            contW      = rect.width,
423            contH      = rect.height,
424            contL      = rect.left,
425            imgW       = _this.image.width,
426            imgH       = _this.image.height,
427            speed      = _this.options.speed,
428            isScroll   = _this.options.type === 'scroll' || _this.options.type === 'scroll-opacity',
429            scrollDist = 0,
430            resultW    = 0,
431            resultH    = contH,
432            resultML   = 0,
433            resultMT   = 0;
434
435        // scroll parallax
436        if(isScroll) {
437            // scroll distance and height for image
438            if (speed < 0) {
439                scrollDist = speed * Math.max(contH, wndH);
440            } else {
441                scrollDist = speed * (contH + wndH);
442            }
443
444            // size for scroll parallax
445            if (speed > 1) {
446                resultH = Math.abs(scrollDist - wndH);
447            } else if (speed < 0) {
448                resultH = scrollDist / speed + Math.abs(scrollDist);
449            }  else {
450                resultH += Math.abs(wndH - contH) * (1 - speed);
451            }
452
453            scrollDist /= 2;
454        }
455
456        // calculate width relative to height and image size
457        resultW = resultH * imgW / imgH;
458        if(resultW < contW) {
459            resultW = contW;
460            resultH = resultW * imgH / imgW;
461        }
462
463        // center parallax image
464        if(isScroll) {
465            resultML = contL + (contW - resultW) / 2;
466            resultMT = (wndH - resultH) / 2;
467        } else {
468            resultML = (contW - resultW) / 2;
469            resultMT = (contH - resultH) / 2;
470        }
471
472        // fix if parallax block in absolute position
473        if(_this.image.position === 'absolute') {
474            resultML -= contL;
475        }
476
477        // store scroll distance
478        _this.parallaxScrollDistance = scrollDist;
479
480        // apply result to item
481        _this.css(_this.image.$item, {
482            width: resultW + 'px',
483            height: resultH + 'px',
484            marginLeft: resultML + 'px',
485            marginTop: resultMT + 'px'
486        });
487
488        // call onCoverImage event
489        if(_this.options.onCoverImage) {
490            _this.options.onCoverImage.call(_this);
491        }
492    };
493
494    Jarallax.prototype.isVisible = function () {
495        return this.isElementInViewport || false;
496    };
497
498    Jarallax.prototype.onScroll = function (force) {
499        var _this = this;
500
501        if(!_this.image.width || !_this.image.height) {
502            return;
503        }
504
505        var rect   = _this.$item.getBoundingClientRect(),
506            contT  = rect.top,
507            contH  = rect.height,
508            styles = {
509                visibility         : 'visible',
510                backgroundPosition : '50% 50%'
511            };
512
513        // check if in viewport
514        var viewportRect = rect;
515        if(_this.options.elementInViewport) {
516            viewportRect = _this.options.elementInViewport.getBoundingClientRect();
517        }
518        _this.isElementInViewport =
519            viewportRect.bottom >= 0 &&
520            viewportRect.right >= 0 &&
521            viewportRect.top <= wndH &&
522            viewportRect.left <= wndW;
523
524        // stop calculations if item is not in viewport
525        if (force ? false : !_this.isElementInViewport) {
526            return;
527        }
528
529        // calculate parallax helping variables
530        var beforeTop = Math.max(0, contT),
531            beforeTopEnd = Math.max(0, contH + contT),
532            afterTop = Math.max(0, -contT),
533            beforeBottom = Math.max(0, contT + contH - wndH),
534            beforeBottomEnd = Math.max(0, contH - (contT + contH - wndH)),
535            afterBottom = Math.max(0, -contT + wndH - contH),
536            fromViewportCenter = 1 - 2 * (wndH - contT) / (wndH + contH);
537
538        // calculate on how percent of section is visible
539        var visiblePercent = 1;
540        if(contH < wndH) {
541            visiblePercent = 1 - (afterTop || beforeBottom) / contH;
542        } else {
543            if(beforeTopEnd <= wndH) {
544                visiblePercent = beforeTopEnd / wndH;
545            } else if (beforeBottomEnd <= wndH) {
546                visiblePercent = beforeBottomEnd / wndH;
547            }
548        }
549
550        // opacity
551        if(_this.options.type === 'opacity' || _this.options.type === 'scale-opacity' || _this.options.type === 'scroll-opacity') {
552            styles.transform = ''; // empty to add translateZ(0) where it is possible
553            styles.opacity = visiblePercent;
554        }
555
556        // scale
557        if(_this.options.type === 'scale' || _this.options.type === 'scale-opacity') {
558            var scale = 1;
559            if(_this.options.speed < 0) {
560                scale -= _this.options.speed * visiblePercent;
561            } else {
562                scale += _this.options.speed * (1 - visiblePercent);
563            }
564            styles.transform = 'scale(' + scale + ')';
565        }
566
567        // scroll
568        if(_this.options.type === 'scroll' || _this.options.type === 'scroll-opacity') {
569            var positionY = _this.parallaxScrollDistance * fromViewportCenter;
570
571            // fix if parallax block in absolute position
572            if(_this.image.position === 'absolute') {
573                positionY -= contT;
574            }
575
576            styles.transform = 'translateY(' + positionY + 'px)';
577        }
578
579        _this.css(_this.image.$item, styles);
580
581        // call onScroll event
582        if(_this.options.onScroll) {
583            _this.options.onScroll.call(_this, {
584                section: rect,
585
586                beforeTop: beforeTop,
587                beforeTopEnd: beforeTopEnd,
588                afterTop: afterTop,
589                beforeBottom: beforeBottom,
590                beforeBottomEnd: beforeBottomEnd,
591                afterBottom: afterBottom,
592
593                visiblePercent: visiblePercent,
594                fromViewportCenter: fromViewportCenter
595            });
596        }
597    };
598
599
600    // init events
601    function addEventListener (el, eventName, handler) {
602        if (el.addEventListener) {
603            el.addEventListener(eventName, handler);
604        } else {
605            el.attachEvent('on' + eventName, function (){
606                handler.call(el);
607            });
608        }
609    }
610
611    function update (e) {
612        window.requestAnimationFrame(function () {
613            if(e.type !== 'scroll') {
614                updateWndVars();
615            }
616            for(var k = 0, len = jarallaxList.length; k < len; k++) {
617                // cover image and clip needed only when parallax container was changed
618                if(e.type !== 'scroll') {
619                    jarallaxList[k].coverImage();
620                    jarallaxList[k].clipContainer();
621                }
622                jarallaxList[k].onScroll();
623            }
624        });
625    }
626    addEventListener(window, 'scroll', update);
627    addEventListener(window, 'resize', update);
628    addEventListener(window, 'orientationchange', update);
629    addEventListener(window, 'load', update);
630
631
632    // global definition
633    var plugin = function (items) {
634        // check for dom element
635        // thanks: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
636        if(typeof HTMLElement === "object" ? items instanceof HTMLElement : items && typeof items === "object" && items !== null && items.nodeType === 1 && typeof items.nodeName==="string") {
637            items = [items];
638        }
639
640        var options = arguments[1],
641            args = Array.prototype.slice.call(arguments, 2),
642            len = items.length,
643            k = 0,
644            ret;
645
646        for (k; k < len; k++) {
647            if (typeof options === 'object' || typeof options === 'undefined') {
648                if(!items[k].jarallax) {
649                    items[k].jarallax = new Jarallax(items[k], options);
650                }
651            }
652            else if(items[k].jarallax) {
653                ret = items[k].jarallax[options].apply(items[k].jarallax, args);
654            }
655            if (typeof ret !== 'undefined') {
656                return ret;
657            }
658        }
659
660        return items;
661    };
662    plugin.constructor = Jarallax;
663
664    // no conflict
665    var oldPlugin = window.jarallax;
666    window.jarallax = plugin;
667    window.jarallax.noConflict = function () {
668        window.jarallax = oldPlugin;
669        return this;
670    };
671
672    // jQuery support
673    if(typeof jQuery !== 'undefined') {
674        var jQueryPlugin = function () {
675            var args = arguments || [];
676            Array.prototype.unshift.call(args, this);
677            var res = plugin.apply(window, args);
678            return typeof res !== 'object' ? res : this;
679        };
680        jQueryPlugin.constructor = Jarallax;
681
682        // no conflict
683        var oldJqPlugin = jQuery.fn.jarallax;
684        jQuery.fn.jarallax = jQueryPlugin;
685        jQuery.fn.jarallax.noConflict = function () {
686            jQuery.fn.jarallax = oldJqPlugin;
687            return this;
688        };
689    }
690
691    // data-jarallax initialization
692    addEventListener(window, 'DOMContentLoaded', function () {
693        plugin(document.querySelectorAll('[data-jarallax], [data-jarallax-video]'));
694    });
695}(window));

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.