Root Zanli
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
home
/
o5t6x7pgljbm
/
public_html
/
tuitioncoin.org
/
assets
/
vendor
/
jarallax
/
dist
/
Filename :
jarallax.js
back
Copy
/*! * Jarallax v2.1.3 (https://github.com/nk-o/jarallax) * Copyright 2022 nK <https://nkdev.info> * Licensed under MIT (https://github.com/nk-o/jarallax/blob/master/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.jarallax = factory()); })(this, (function () { 'use strict'; /** * Document ready callback. * @param {Function} callback - callback will be fired once Document ready. */ function ready(callback) { if (document.readyState === 'complete' || document.readyState === 'interactive') { // Already ready or interactive, execute callback callback(); } else { document.addEventListener('DOMContentLoaded', callback, { capture: true, once: true, passive: true }); } } /* eslint-disable import/no-mutable-exports */ /* eslint-disable no-restricted-globals */ let win; if (typeof window !== 'undefined') { win = window; } else if (typeof global !== 'undefined') { win = global; } else if (typeof self !== 'undefined') { win = self; } else { win = {}; } var global$1 = win; var defaults = { // Base parallax options. type: 'scroll', speed: 0.5, containerClass: 'jarallax-container', imgSrc: null, imgElement: '.jarallax-img', imgSize: 'cover', imgPosition: '50% 50%', imgRepeat: 'no-repeat', keepImg: false, elementInViewport: null, zIndex: -100, disableParallax: false, // Callbacks. onScroll: null, onInit: null, onDestroy: null, onCoverImage: null, // Video options. videoClass: 'jarallax-video', videoSrc: null, videoStartTime: 0, videoEndTime: 0, videoVolume: 0, videoLoop: true, videoPlayOnlyVisible: true, videoLazyLoading: true, disableVideo: false, // Video callbacks. onVideoInsert: null, onVideoWorkerInit: null }; /** * Add styles to element. * * @param {Element} el - element. * @param {String|Object} styles - styles list. * * @returns {Element} */ function css(el, styles) { if (typeof styles === 'string') { return global$1.getComputedStyle(el).getPropertyValue(styles); } Object.keys(styles).forEach(key => { el.style[key] = styles[key]; }); return el; } /** * Extend like jQuery.extend * * @param {Object} out - output object. * @param {...any} args - additional objects to extend. * * @returns {Object} */ function extend(out, ...args) { out = out || {}; Object.keys(args).forEach(i => { if (!args[i]) { return; } Object.keys(args[i]).forEach(key => { out[key] = args[i][key]; }); }); return out; } /** * Get all parents of the element. * * @param {Element} elem - DOM element. * * @returns {Array} */ function getParents(elem) { const parents = []; while (elem.parentElement !== null) { elem = elem.parentElement; if (elem.nodeType === 1) { parents.push(elem); } } return parents; } const { navigator: navigator$1 } = global$1; const mobileAgent = /*#__PURE__*/ /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator$1.userAgent); function isMobile() { return mobileAgent; } let wndW; let wndH; let $deviceHelper; /** * The most popular mobile browsers changes height after page scroll and this generates image jumping. * We can fix it using this workaround with vh units. */ function getDeviceHeight() { if (!$deviceHelper && document.body) { $deviceHelper = document.createElement('div'); $deviceHelper.style.cssText = 'position: fixed; top: -9999px; left: 0; height: 100vh; width: 0;'; document.body.appendChild($deviceHelper); } return ($deviceHelper ? $deviceHelper.clientHeight : 0) || global$1.innerHeight || document.documentElement.clientHeight; } function updateWindowHeight() { wndW = global$1.innerWidth || document.documentElement.clientWidth; if (isMobile()) { wndH = getDeviceHeight(); } else { wndH = global$1.innerHeight || document.documentElement.clientHeight; } } updateWindowHeight(); global$1.addEventListener('resize', updateWindowHeight); global$1.addEventListener('orientationchange', updateWindowHeight); global$1.addEventListener('load', updateWindowHeight); ready(() => { updateWindowHeight(); }); function getWindowSize() { return { width: wndW, height: wndH }; } // List with all jarallax instances // need to render all in one scroll/resize event. const jarallaxList = []; function updateParallax() { if (!jarallaxList.length) { return; } const { width: wndW, height: wndH } = getWindowSize(); jarallaxList.forEach((data, k) => { const { instance, oldData } = data; if (!instance.isVisible()) { return; } const clientRect = instance.$item.getBoundingClientRect(); const newData = { width: clientRect.width, height: clientRect.height, top: clientRect.top, bottom: clientRect.bottom, wndW, wndH }; const isResized = !oldData || oldData.wndW !== newData.wndW || oldData.wndH !== newData.wndH || oldData.width !== newData.width || oldData.height !== newData.height; const isScrolled = isResized || !oldData || oldData.top !== newData.top || oldData.bottom !== newData.bottom; jarallaxList[k].oldData = newData; if (isResized) { instance.onResize(); } if (isScrolled) { instance.onScroll(); } }); global$1.requestAnimationFrame(updateParallax); } const visibilityObserver = /*#__PURE__*/new global$1.IntersectionObserver(entries => { entries.forEach(entry => { entry.target.jarallax.isElementInViewport = entry.isIntersecting; }); }, { // We have to start parallax calculation before the block is in view // to prevent possible parallax jumping. rootMargin: '50px' }); function addObserver(instance) { jarallaxList.push({ instance }); if (jarallaxList.length === 1) { global$1.requestAnimationFrame(updateParallax); } visibilityObserver.observe(instance.options.elementInViewport || instance.$item); } function removeObserver(instance) { jarallaxList.forEach((data, key) => { if (data.instance.instanceID === instance.instanceID) { jarallaxList.splice(key, 1); } }); visibilityObserver.unobserve(instance.options.elementInViewport || instance.$item); } /* eslint-disable class-methods-use-this */ const { navigator } = global$1; let instanceID = 0; // Jarallax class class Jarallax { constructor(item, userOptions) { const self = this; self.instanceID = instanceID; instanceID += 1; self.$item = item; self.defaults = { ...defaults }; // prepare data-options const dataOptions = self.$item.dataset || {}; const pureDataOptions = {}; Object.keys(dataOptions).forEach(key => { const lowerCaseOption = key.substr(0, 1).toLowerCase() + key.substr(1); if (lowerCaseOption && typeof self.defaults[lowerCaseOption] !== 'undefined') { pureDataOptions[lowerCaseOption] = dataOptions[key]; } }); self.options = self.extend({}, self.defaults, pureDataOptions, userOptions); self.pureOptions = self.extend({}, self.options); // prepare 'true' and 'false' strings to boolean Object.keys(self.options).forEach(key => { if (self.options[key] === 'true') { self.options[key] = true; } else if (self.options[key] === 'false') { self.options[key] = false; } }); // fix speed option [-1.0, 2.0] self.options.speed = Math.min(2, Math.max(-1, parseFloat(self.options.speed))); // prepare disableParallax callback if (typeof self.options.disableParallax === 'string') { self.options.disableParallax = new RegExp(self.options.disableParallax); } if (self.options.disableParallax instanceof RegExp) { const disableParallaxRegexp = self.options.disableParallax; self.options.disableParallax = () => disableParallaxRegexp.test(navigator.userAgent); } if (typeof self.options.disableParallax !== 'function') { self.options.disableParallax = () => false; } // prepare disableVideo callback if (typeof self.options.disableVideo === 'string') { self.options.disableVideo = new RegExp(self.options.disableVideo); } if (self.options.disableVideo instanceof RegExp) { const disableVideoRegexp = self.options.disableVideo; self.options.disableVideo = () => disableVideoRegexp.test(navigator.userAgent); } if (typeof self.options.disableVideo !== 'function') { self.options.disableVideo = () => false; } // custom element to check if parallax in viewport let elementInVP = self.options.elementInViewport; // get first item from array if (elementInVP && typeof elementInVP === 'object' && typeof elementInVP.length !== 'undefined') { [elementInVP] = elementInVP; } // check if dom element if (!(elementInVP instanceof Element)) { elementInVP = null; } self.options.elementInViewport = elementInVP; self.image = { src: self.options.imgSrc || null, $container: null, useImgTag: false, // 1. Position fixed is needed for the most of browsers because absolute position have glitches // 2. On MacOS with smooth scroll there is a huge lags with absolute position - https://github.com/nk-o/jarallax/issues/75 // 3. Previously used 'absolute' for mobile devices. But we re-tested on iPhone 12 and 'fixed' position is working better, then 'absolute', so for now position is always 'fixed' position: 'fixed' }; if (self.initImg() && self.canInitParallax()) { self.init(); } } css(el, styles) { return css(el, styles); } extend(out, ...args) { return extend(out, ...args); } // get window size and scroll position. Useful for extensions getWindowData() { const { width, height } = getWindowSize(); return { width, height, y: document.documentElement.scrollTop }; } // Jarallax functions initImg() { const self = this; // find image element let $imgElement = self.options.imgElement; if ($imgElement && typeof $imgElement === 'string') { $imgElement = self.$item.querySelector($imgElement); } // check if dom element if (!($imgElement instanceof Element)) { if (self.options.imgSrc) { $imgElement = new Image(); $imgElement.src = self.options.imgSrc; } else { $imgElement = null; } } if ($imgElement) { if (self.options.keepImg) { self.image.$item = $imgElement.cloneNode(true); } else { self.image.$item = $imgElement; self.image.$itemParent = $imgElement.parentNode; } self.image.useImgTag = true; } // true if there is img tag if (self.image.$item) { return true; } // get image src if (self.image.src === null) { self.image.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; self.image.bgImage = self.css(self.$item, 'background-image'); } return !(!self.image.bgImage || self.image.bgImage === 'none'); } canInitParallax() { return !this.options.disableParallax(); } init() { const self = this; const containerStyles = { position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', overflow: 'hidden' }; let imageStyles = { pointerEvents: 'none', transformStyle: 'preserve-3d', backfaceVisibility: 'hidden' }; if (!self.options.keepImg) { // save default user styles const curStyle = self.$item.getAttribute('style'); if (curStyle) { self.$item.setAttribute('data-jarallax-original-styles', curStyle); } if (self.image.useImgTag) { const curImgStyle = self.image.$item.getAttribute('style'); if (curImgStyle) { self.image.$item.setAttribute('data-jarallax-original-styles', curImgStyle); } } } // set relative position and z-index to the parent if (self.css(self.$item, 'position') === 'static') { self.css(self.$item, { position: 'relative' }); } if (self.css(self.$item, 'z-index') === 'auto') { self.css(self.$item, { zIndex: 0 }); } // container for parallax image self.image.$container = document.createElement('div'); self.css(self.image.$container, containerStyles); self.css(self.image.$container, { 'z-index': self.options.zIndex }); // it will remove some image overlapping // overlapping occur due to an image position fixed inside absolute position element // needed only when background in fixed position if (this.image.position === 'fixed') { self.css(self.image.$container, { '-webkit-clip-path': 'polygon(0 0, 100% 0, 100% 100%, 0 100%)', 'clip-path': 'polygon(0 0, 100% 0, 100% 100%, 0 100%)' }); } // Add container unique ID. self.image.$container.setAttribute('id', `jarallax-container-${self.instanceID}`); // Add container class. if (self.options.containerClass) { self.image.$container.setAttribute('class', self.options.containerClass); } self.$item.appendChild(self.image.$container); // use img tag if (self.image.useImgTag) { imageStyles = self.extend({ 'object-fit': self.options.imgSize, 'object-position': self.options.imgPosition, 'max-width': 'none' }, containerStyles, imageStyles); // use div with background image } else { self.image.$item = document.createElement('div'); if (self.image.src) { imageStyles = self.extend({ 'background-position': self.options.imgPosition, 'background-size': self.options.imgSize, 'background-repeat': self.options.imgRepeat, 'background-image': self.image.bgImage || `url("${self.image.src}")` }, containerStyles, imageStyles); } } if (self.options.type === 'opacity' || self.options.type === 'scale' || self.options.type === 'scale-opacity' || self.options.speed === 1) { self.image.position = 'absolute'; } // 1. Check if one of parents have transform style (without this check, scroll transform will be inverted if used parallax with position fixed) // discussion - https://github.com/nk-o/jarallax/issues/9 // 2. Check if parents have overflow scroll if (self.image.position === 'fixed') { const $parents = getParents(self.$item).filter(el => { const styles = global$1.getComputedStyle(el); const parentTransform = styles['-webkit-transform'] || styles['-moz-transform'] || styles.transform; const overflowRegex = /(auto|scroll)/; return parentTransform && parentTransform !== 'none' || overflowRegex.test(styles.overflow + styles['overflow-y'] + styles['overflow-x']); }); self.image.position = $parents.length ? 'absolute' : 'fixed'; } // add position to parallax block imageStyles.position = self.image.position; // insert parallax image self.css(self.image.$item, imageStyles); self.image.$container.appendChild(self.image.$item); // set initial position and size self.onResize(); self.onScroll(true); // call onInit event if (self.options.onInit) { self.options.onInit.call(self); } // remove default user background if (self.css(self.$item, 'background-image') !== 'none') { self.css(self.$item, { 'background-image': 'none' }); } addObserver(self); } destroy() { const self = this; removeObserver(self); // return styles on container as before jarallax init const originalStylesTag = self.$item.getAttribute('data-jarallax-original-styles'); self.$item.removeAttribute('data-jarallax-original-styles'); // null occurs if there is no style tag before jarallax init if (!originalStylesTag) { self.$item.removeAttribute('style'); } else { self.$item.setAttribute('style', originalStylesTag); } if (self.image.useImgTag) { // return styles on img tag as before jarallax init const originalStylesImgTag = self.image.$item.getAttribute('data-jarallax-original-styles'); self.image.$item.removeAttribute('data-jarallax-original-styles'); // null occurs if there is no style tag before jarallax init if (!originalStylesImgTag) { self.image.$item.removeAttribute('style'); } else { self.image.$item.setAttribute('style', originalStylesTag); } // move img tag to its default position if (self.image.$itemParent) { self.image.$itemParent.appendChild(self.image.$item); } } // remove additional dom elements if (self.image.$container) { self.image.$container.parentNode.removeChild(self.image.$container); } // call onDestroy event if (self.options.onDestroy) { self.options.onDestroy.call(self); } // delete jarallax from item delete self.$item.jarallax; } coverImage() { const self = this; const { height: wndH } = getWindowSize(); const rect = self.image.$container.getBoundingClientRect(); const contH = rect.height; const { speed } = self.options; const isScroll = self.options.type === 'scroll' || self.options.type === 'scroll-opacity'; let scrollDist = 0; let resultH = contH; let resultMT = 0; // scroll parallax if (isScroll) { // scroll distance and height for image if (speed < 0) { scrollDist = speed * Math.max(contH, wndH); if (wndH < contH) { scrollDist -= speed * (contH - wndH); } } else { scrollDist = speed * (contH + wndH); } // size for scroll parallax if (speed > 1) { resultH = Math.abs(scrollDist - wndH); } else if (speed < 0) { resultH = scrollDist / speed + Math.abs(scrollDist); } else { resultH += (wndH - contH) * (1 - speed); } scrollDist /= 2; } // store scroll distance self.parallaxScrollDistance = scrollDist; // vertical center if (isScroll) { resultMT = (wndH - resultH) / 2; } else { resultMT = (contH - resultH) / 2; } // apply result to item self.css(self.image.$item, { height: `${resultH}px`, marginTop: `${resultMT}px`, left: self.image.position === 'fixed' ? `${rect.left}px` : '0', width: `${rect.width}px` }); // call onCoverImage event if (self.options.onCoverImage) { self.options.onCoverImage.call(self); } // return some useful data. Used in the video cover function return { image: { height: resultH, marginTop: resultMT }, container: rect }; } isVisible() { return this.isElementInViewport || false; } onScroll(force) { const self = this; // stop calculations if item is not in viewport if (!force && !self.isVisible()) { return; } const { height: wndH } = getWindowSize(); const rect = self.$item.getBoundingClientRect(); const contT = rect.top; const contH = rect.height; const styles = {}; // calculate parallax helping variables const beforeTop = Math.max(0, contT); const beforeTopEnd = Math.max(0, contH + contT); const afterTop = Math.max(0, -contT); const beforeBottom = Math.max(0, contT + contH - wndH); const beforeBottomEnd = Math.max(0, contH - (contT + contH - wndH)); const afterBottom = Math.max(0, -contT + wndH - contH); const fromViewportCenter = 1 - 2 * ((wndH - contT) / (wndH + contH)); // calculate on how percent of section is visible let visiblePercent = 1; if (contH < wndH) { visiblePercent = 1 - (afterTop || beforeBottom) / contH; } else if (beforeTopEnd <= wndH) { visiblePercent = beforeTopEnd / wndH; } else if (beforeBottomEnd <= wndH) { visiblePercent = beforeBottomEnd / wndH; } // opacity if (self.options.type === 'opacity' || self.options.type === 'scale-opacity' || self.options.type === 'scroll-opacity') { styles.transform = 'translate3d(0,0,0)'; styles.opacity = visiblePercent; } // scale if (self.options.type === 'scale' || self.options.type === 'scale-opacity') { let scale = 1; if (self.options.speed < 0) { scale -= self.options.speed * visiblePercent; } else { scale += self.options.speed * (1 - visiblePercent); } styles.transform = `scale(${scale}) translate3d(0,0,0)`; } // scroll if (self.options.type === 'scroll' || self.options.type === 'scroll-opacity') { let positionY = self.parallaxScrollDistance * fromViewportCenter; // fix if parallax block in absolute position if (self.image.position === 'absolute') { positionY -= contT; } styles.transform = `translate3d(0,${positionY}px,0)`; } self.css(self.image.$item, styles); // call onScroll event if (self.options.onScroll) { self.options.onScroll.call(self, { section: rect, beforeTop, beforeTopEnd, afterTop, beforeBottom, beforeBottomEnd, afterBottom, visiblePercent, fromViewportCenter }); } } onResize() { this.coverImage(); } } // global definition const jarallax = function (items, options, ...args) { // check for dom element // thanks: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object if (typeof HTMLElement === 'object' ? items instanceof HTMLElement : items && typeof items === 'object' && items !== null && items.nodeType === 1 && typeof items.nodeName === 'string') { items = [items]; } const len = items.length; let k = 0; let ret; for (k; k < len; k += 1) { if (typeof options === 'object' || typeof options === 'undefined') { if (!items[k].jarallax) { items[k].jarallax = new Jarallax(items[k], options); } } else if (items[k].jarallax) { // eslint-disable-next-line prefer-spread ret = items[k].jarallax[options].apply(items[k].jarallax, args); } if (typeof ret !== 'undefined') { return ret; } } return items; }; jarallax.constructor = Jarallax; const $ = global$1.jQuery; // jQuery support if (typeof $ !== 'undefined') { const $Plugin = function (...args) { Array.prototype.unshift.call(args, this); const res = jarallax.apply(global$1, args); return typeof res !== 'object' ? res : this; }; $Plugin.constructor = jarallax.constructor; // no conflict const old$Plugin = $.fn.jarallax; $.fn.jarallax = $Plugin; $.fn.jarallax.noConflict = function () { $.fn.jarallax = old$Plugin; return this; }; } // data-jarallax initialization ready(() => { jarallax(document.querySelectorAll('[data-jarallax]')); }); return jarallax; })); //# sourceMappingURL=jarallax.js.map