{"version":3,"file":"parallax.min.js","sources":["../src/browser.ts","../src/consts.ts","../src/utils.ts","../src/Parallax.ts"],"sourcesContent":["import { WindowMockType } from \"./types\";\n\nlet win: WindowMockType;\n\nif (typeof window === \"undefined\") {\n\t// window is undefined in node.js\n\twin = {\n\t\tdocument: {},\n\t\tnavigator: {\n\t\t\tuserAgent: \"\",\n\t\t},\n\t};\n} else {\n\twin = window;\n}\n\nexport { win as window };\nexport const document = win.document;\n","import { window, document } from \"./browser\";\nimport { IAlign } from \"./types\";\n\nconst ua = window.navigator.userAgent;\n\nexport const SUPPORT_COMPUTEDSTYLE = !!(\"getComputedStyle\" in window);\nexport const SUPPORT_ADDEVENTLISTENER = !!(\"addEventListener\" in document);\nexport const SUPPORT_PASSIVE = (() => {\n\tlet supportsPassiveOption = false;\n\n\ttry {\n\t\tif (SUPPORT_ADDEVENTLISTENER && Object.defineProperty) {\n\t\t\tdocument.addEventListener(\"test\", null, Object.defineProperty({},\n\t\t\t\t\"passive\", {\n\t\t\t\t\tget() {\n\t\t\t\t\t\tsupportsPassiveOption = true;\n\t\t\t\t\t},\n\t\t\t\t}));\n\t\t}\n\t} catch (e) {\n\t\t//\n\t}\n\treturn supportsPassiveOption;\n})();\n\nexport const IS_IE = /MSIE|Trident|Windows Phone|Edge/.test(ua);\nexport const IS_IOS = /iPhone|iPad/.test(ua);\nexport const IS_ANDROID2 = /Android 2\\./.test(ua);\nexport const CONTAINER_CLASSNAME = \"_eg-infinitegrid-container_\";\nexport const IGNORE_CLASSNAME = \"_eg-infinitegrid-ignore_\";\nexport const TRANSITION_NAME = \"_INFINITEGRID_TRANSITION\";\n\nexport const APPEND = true;\nexport const PREPEND = false;\nexport const VERTICAL = \"vertical\";\nexport const HORIZONTAL = \"horizontal\";\nexport const CACHE = true;\nexport const NO_CACHE = false;\nexport const TRUSTED = true;\nexport const NO_TRUSTED = false;\nexport const MULTI = true;\nexport const SINGLE = false;\nexport const DUMMY_POSITION = -100000;\nexport const GROUPKEY_ATT = \"data-groupkey\";\n\nexport const DEFAULT_OPTIONS = {\n\thorizontal: false,\n\tmargin: 0,\n};\n\nexport const agent = ua.toLowerCase();\nexport const isMobile = /mobi|ios|android/.test(agent);\n\nexport const ALIGN: IAlign = {\n\tSTART: \"start\",\n\tCENTER: \"center\",\n\tEND: \"end\",\n\tJUSTIFY: \"justify\",\n};\n\nexport const IDLE = 0;\nexport const LOADING_APPEND = 1;\nexport const LOADING_PREPEND = 2;\nexport const PROCESSING = 4;\n\nconst webkit = /applewebkit\\/([\\d|.]*)/g.exec(agent);\n\nexport const WEBKIT_VERSION = (webkit && parseInt(webkit[1], 10)) || 0;\nexport const DEFENSE_BROWSER = (WEBKIT_VERSION && WEBKIT_VERSION < 537);\n\ninterface ITransitionEnd {\n\ttransitionend: string;\n\twebkitTransitionEnd: string;\n\tMSTransitionEnd: string;\n\toTransitionEnd: string;\n\tmozTransitionEnd: string;\n}\n\nexport const [TRANSFORM, TRANSITION, TRANSITION_END] = (() => {\n\tconst properties: ITransitionEnd = {\n\t\ttransitionend: \"\",\n\t\twebkitTransitionEnd: \"-webkit-\",\n\t\tMSTransitionEnd: \"-ms-\",\n\t\toTransitionEnd: \"-o-\",\n\t\tmozTransitionEnd: \"-moz-\",\n\t};\n\n\tfor (const property in properties) {\n\t\tconst prefix = properties[property as keyof ITransitionEnd];\n\n\t\tif (`on${property.toLowerCase()}` in window) {\n\t\t\treturn [`${prefix}transform`, `${prefix}transition`, property];\n\t\t}\n\t}\n\treturn [];\n})() as [\"transform\", \"transition\", \"transitionend\"];\n","\nimport { window, document } from \"./browser\";\nimport {\n\tSUPPORT_COMPUTEDSTYLE,\n\tSUPPORT_ADDEVENTLISTENER,\n\tSUPPORT_PASSIVE,\n\tVERTICAL,\n\tHORIZONTAL,\n\tDEFAULT_OPTIONS,\n} from \"./consts\";\nimport { IJQuery, IRectlProperties, InnerSizeType, ClientSizeType, ScrollSizeType, OffsetSizeType, WindowMockType } from \"./types\";\n\nexport function toArray(nodes: HTMLCollection): HTMLElement[];\nexport function toArray(nodes: T[] | NodeListOf): T[];\nexport function toArray(nodes: T[] | NodeListOf | HTMLCollection) {\n\t// SCRIPT5014 in IE8\n\tconst array = [];\n\n\tif (nodes) {\n\t\tfor (let i = 0, len = nodes.length; i < len; i++) {\n\t\t\tarray.push(nodes[i]);\n\t\t}\n\t}\n\treturn array;\n}\nexport function matchHTML(html: string) {\n\treturn html.match(/^<([A-z]+)\\s*([^>]*)>/);\n}\n/**\n * Select or create element\n * @param {String|HTMLElement|jQuery} param\n * when string given is as HTML tag, then create element\n * otherwise it returns selected elements\n * @param {Boolean} multi\n * @returns {HTMLElement}\n */\nexport function $(param: WindowMockType, multi?: false): WindowMockType;\nexport function $(\n\tparam: string | HTMLElement | Array | IJQuery,\n\tmulti: true,\n): HTMLElement[];\nexport function $(\n\tparam: string | HTMLElement | Array | IJQuery,\n\tmulti?: false,\n): HTMLElement;\nexport function $(\n\tparam: string | HTMLElement | WindowMockType | IJQuery,\n\tmulti?: false,\n): HTMLElement | WindowMockType;\nexport function $(\n\tparam: string | WindowMockType | HTMLElement | Array | IJQuery,\n\tmulti = false,\n): HTMLElement | WindowMockType | HTMLElement[] {\n\tlet el: WindowMockType | HTMLElement | HTMLElement[] | NodeListOf;\n\n\tif (typeof param === \"string\") { // String (HTML, Selector)\n\t\t// check if string is HTML tag format\n\t\tconst match = matchHTML(param);\n\n\t\t// creating element\n\t\tif (match) { // HTML\n\t\t\tconst dummy = document.createElement(\"div\");\n\n\t\t\tdummy.innerHTML = param;\n\t\t\tel = dummy.childNodes as NodeListOf;\n\t\t} else { // Selector\n\t\t\tel = document.querySelectorAll(param);\n\t\t}\n\t\tif (multi) {\n\t\t\treturn toArray(el as NodeListOf);\n\t\t} else {\n\t\t\treturn el && (el as NodeListOf)[0];\n\t\t}\n\t} else if (isWindow(param)) { // window\n\t\tel = param;\n\t} else if (isJQuery(param)) { // jQuery\n\t\tel = multi ? $(param.toArray(), true) :\n\t\t\t$(param.get(0), false);\n\t} else if (Array.isArray(param)) {\n\t\tel = param.map(v => $(v));\n\t\tif (!multi) {\n\t\t\tel = el.length >= 1 ? (el as HTMLElement[])[0] : undefined;\n\t\t}\n\t} else if (param.nodeName &&\n\t\t(param.nodeType === 1 || param.nodeType === 9)) { // HTMLElement, Document\n\t\tel = param;\n\t}\n\treturn el;\n}\nexport function addEvent(\n\telement: Element | WindowMockType,\n\ttype: string,\n\thandler: (...args: any[]) => any,\n\teventListenerOptions?: boolean | { [key: string]: any },\n) {\n\tif (SUPPORT_ADDEVENTLISTENER) {\n\t\tlet options = eventListenerOptions || false;\n\n\t\tif (typeof eventListenerOptions === \"object\") {\n\t\t\toptions = SUPPORT_PASSIVE ? eventListenerOptions : false;\n\t\t}\n\t\telement.addEventListener(type, handler, options);\n\t} else if ((element as any).attachEvent) {\n\t\t(element as any).attachEvent(`on${type}`, handler);\n\t} else {\n\t\t(element as any)[`on${type}`] = handler;\n\t}\n}\nexport function removeEvent(\n\telement: Element | WindowMockType,\n\ttype: string,\n\thandler: (...args: any[]) => any,\n) {\n\tif (element.removeEventListener) {\n\t\telement.removeEventListener(type, handler, false);\n\t} else if ((element as any).detachEvent) {\n\t\t(element as any).detachEvent(`on${type}`, handler);\n\t} else {\n\t\t(element as any)[`on${type}`] = null;\n\t}\n}\nexport function addOnceEvent(\n\telement: Element,\n\ttype: string,\n\thandler: (...args: any[]) => any,\n\teventListenerOptions?: boolean | { [key: string]: any },\n) {\n\tconst callback = (e: any) => {\n\t\tremoveEvent(element, type, callback);\n\t\thandler(e);\n\t};\n\n\taddEvent(element, type, callback, eventListenerOptions);\n}\nexport function scroll(el: HTMLElement | WindowMockType, horizontal = false) {\n\tconst prop = `scroll${horizontal ? \"Left\" : \"Top\"}` as \"scrollLeft\" | \"scrollTop\";\n\n\tif (isWindow(el)) {\n\t\treturn window[horizontal ? \"pageXOffset\" : \"pageYOffset\"] || document.body[prop] || document.documentElement[prop];\n\t} else {\n\t\treturn el[prop];\n\t}\n}\nexport function scrollTo(el: WindowMockType | Element, x: number, y: number) {\n\tif (isWindow(el)) {\n\t\tel.scroll(x, y);\n\t} else {\n\t\tel.scrollLeft = x;\n\t\tel.scrollTop = y;\n\t}\n}\nexport function scrollBy(el: WindowMockType | Element, x: number, y: number) {\n\tif (isWindow(el)) {\n\t\tel.scrollBy(x, y);\n\t} else {\n\t\tel.scrollLeft += x;\n\t\tel.scrollTop += y;\n\t}\n}\nexport function getStyles(el: Element) {\n\treturn (SUPPORT_COMPUTEDSTYLE ?\n\t\twindow.getComputedStyle(el) : (el as any).currentStyle) || {};\n}\nfunction _getSize(el: WindowMockType | Document | HTMLElement, name: \"Width\" | \"Height\", isOffset?: boolean) {\n\tif (isWindow(el)) { // WINDOW\n\t\treturn window[`inner${name}` as InnerSizeType] || document.body[`client${name}` as ClientSizeType];\n\t} else if (isDocument(el)) { // DOCUMENT_NODE\n\t\tconst doc = (el as Document).documentElement;\n\t\tconst body = (el as Document).body;\n\n\t\treturn Math.max(\n\t\t\tbody[`scroll${name}` as ScrollSizeType], doc[`scroll${name}` as ScrollSizeType],\n\t\t\tbody[`offset${name}` as OffsetSizeType], doc[`offset${name}` as OffsetSizeType],\n\t\t\tdoc[`client${name}` as ClientSizeType],\n\t\t);\n\t} else { // NODE\n\t\tlet size = 0;\n\n\t\tif (isOffset) {\n\t\t\tconst clientRect = el.getBoundingClientRect();\n\n\t\t\tsize = name === \"Width\" ? clientRect.right - clientRect.left : clientRect.bottom - clientRect.top;\n\t\t} else {\n\t\t\tsize = el[`client${name}` as ClientSizeType] || el[`offset${name}` as OffsetSizeType];\n\t\t}\n\t\treturn parseFloat(size || getStyles(el)[name.toLowerCase()]) || 0;\n\t}\n}\n\nexport function innerWidth(el: WindowMockType | Document | HTMLElement) {\n\treturn _getSize(el, \"Width\", false);\n}\nexport function innerHeight(el: WindowMockType | Document | HTMLElement) {\n\treturn _getSize(el, \"Height\", false);\n}\nexport function outerWidth(el: WindowMockType | Document | HTMLElement) {\n\treturn _getSize(el, \"Width\", true);\n}\nexport function outerHeight(el: WindowMockType | Document | HTMLElement) {\n\treturn _getSize(el, \"Height\", true);\n}\nexport function getSize(el: HTMLElement) {\n\treturn {\n\t\twidth: outerWidth(el),\n\t\theight: outerHeight(el),\n\t};\n}\nexport const STYLE: {\n\tvertical: IRectlProperties,\n\thorizontal: IRectlProperties,\n} = {\n\tvertical: {\n\t\tstartPos1: \"top\",\n\t\tendPos1: \"bottom\",\n\t\tsize1: \"height\",\n\t\tstartPos2: \"left\",\n\t\tendPos2: \"right\",\n\t\tsize2: \"width\",\n\t},\n\thorizontal: {\n\t\tstartPos1: \"left\",\n\t\tendPos1: \"right\",\n\t\tsize1: \"width\",\n\t\tstartPos2: \"top\",\n\t\tendPos2: \"bottom\",\n\t\tsize2: \"height\",\n\t},\n};\n\nexport function getStyleNames(isHorizontal: boolean): IRectlProperties {\n\treturn STYLE[isHorizontal ? HORIZONTAL : VERTICAL];\n}\nexport function assign(target: A, source: B): A & B;\nexport function assign(target: A, source1: B, source2: C): A & B & C;\nexport function assign(target: A, source1: B, source2: C, source3: D): A & B & C & D;\nexport function assign(target: { [key: string]: any }, ...sources: Array<{ [key: string]: any }>): { [key: string]: any };\nexport function assign(target: { [key: string]: any }, ...sources: Array<{ [key: string]: any }>) {\n\tsources.forEach(source => {\n\t\tfor (const key in source) {\n\t\t\ttarget[key] = source[key];\n\t\t}\n\t});\n\treturn target;\n}\nexport function assignOptions(\n\tdefaultOptions: A, options: B): typeof DEFAULT_OPTIONS & A & B {\n\treturn assign({},\n\t\tDEFAULT_OPTIONS,\n\t\tdefaultOptions,\n\t\toptions);\n}\n\nexport function toZeroArray(outline?: number[]) {\n\tif (!outline || !outline.length) {\n\t\treturn [0];\n\t}\n\treturn outline;\n}\nexport function cloneItems(items: T[]) {\n\treturn items.map(item => assign({}, item));\n}\nexport function isJQuery(el: any): el is IJQuery {\n\treturn (typeof (window as any).jQuery === \"function\" && el instanceof (window as any).jQuery) ||\n\t\tel.constructor.prototype.jquery && el.toArray;\n}\nexport function isWindow(el: any): el is WindowMockType {\n\treturn el === window;\n}\nexport function isDocument(el: Node): el is Document {\n\treturn el.nodeType === 9;\n}\n\nexport function fill(arr: T[], value: T) {\n\tconst length = arr.length;\n\n\tfor (let i = length - 1; i >= 0; --i) {\n\t\tarr[i] = value;\n\t}\n\n\treturn arr;\n}\n\nexport function isUndefined(target: any): target is undefined {\n\treturn typeof target === \"undefined\";\n}\n","import { ALIGN, isMobile, TRANSFORM } from \"./consts\";\nimport { $, isWindow, assign } from \"./utils\";\nimport { IAlign, IJQuery, PositionType, SizeType, InnerSizeType, ClientSizeType, IInfiniteGridItemElement, OffsetSizeType, WindowMockType, IInfiniteGridItem } from \"./types\";\n\ninterface IParallaxStyle {\n\tposition: PositionType;\n\tsize: SizeType;\n\tcammelSize: string;\n\tcoordinate: string;\n}\nconst style: {\n\tvertical: IParallaxStyle;\n\thorizontal: IParallaxStyle;\n} = {\n\tvertical: { position: \"top\", size: \"height\", cammelSize: \"Height\", coordinate: \"Y\" },\n\thorizontal: { position: \"left\", size: \"width\", cammelSize: \"Width\", coordinate: \"X\" },\n};\nconst { START, CENTER } = ALIGN;\n\n/**\n * @classdesc Parallax is a displacement or difference in the apparent position of an object viewed along two different lines of sight. You can apply parallax by scrolling the image and speed of the item.\n * @ko Parallax는 서로 다른 두 개의 시선에서 바라본 물체의 외관상 위치의 변위 또는 차이입니다. 스크롤에 따라 이미지와 아이템의 속도를 차이를 줌으로써 parallax을 적용할 수 있습니다.\n * @class eg.Parallax\n * @param {Element|String} [root=window] Scrolling target. If you scroll in the body, set window. 스크롤하는 대상. 만약 body에서 스크롤하면 window로 설정한다.\n * @param {Object} [options] The option object of eg.Parallax module eg.Parallax 모듈의 옵션 객체\n * @param {Boolean} [options.horizontal=false] Direction of the scroll movement (false: vertical, true: horizontal) 스크롤 이동 방향 (false: 세로방향, true: 가로방향)\n * @param {Element|String} [options.container=null] Container wrapping items. If root and container have no gaps, do not set option. 아이템들을 감싸고 있는 컨테이너. 만약 root와 container간의 차이가 없으면, 옵션을 설정하지 않아도 된다.\n * @param {String} [options.selector=\"img\"] The selector of the image to apply the parallax in the item 아이템안에 있는 parallax를 적용할 이미지의 selector \n * @param {Boolean} [options.strength=1] Dimensions that indicate the sensitivity of parallax. The higher the strength, the faster.\n * @param {Boolean} [options.center=0] The middle point of parallax. The top is 1 and the bottom is -1. parallax가 가운데로 오는 점. 상단이 1이고 하단이 -1이다. \n * @param {Boolean} [options.range=[-1, 1]] Range to apply the parallax. The top is 1 and the bottom is -1. parallax가 적용되는 범위, 상단이 1이고 하단이 -1이다. \n * @param {Boolean} [options.align=\"start\"] The alignment of the image in the item. (\"start\" : top or left, \"center\": middle) 아이템안의 이미지의 정렬 \n * @example\n```\n\n```\n **/\nclass Parallax {\n\tpublic options: {\n\t\tcontainer: HTMLElement;\n\t\tselector: string;\n\t\tstrength: number;\n\t\tcenter: number;\n\t\trange: number[];\n\t\talign: IAlign[keyof IAlign];\n\t\thorizontal: boolean;\n\t};\n\tprivate _root: WindowMockType | HTMLElement;\n\tprivate _container: HTMLElement;\n\tprivate _rootSize: number;\n\tprivate _containerPosition: number;\n\tprivate _style: IParallaxStyle;\n\tconstructor(\n\t\troot: WindowMockType | HTMLElement | IJQuery | string = window,\n\t\toptions: Partial = {}) {\n\t\tthis.options = assign({\n\t\t\tcontainer: null,\n\t\t\tselector: \"img\",\n\t\t\tstrength: 1,\n\t\t\tcenter: 0,\n\t\t\trange: [-1, 1],\n\t\t\talign: START,\n\t\t\thorizontal: false,\n\t\t}, options);\n\t\tthis._root = $(root);\n\t\tthis._container = this.options.container && $(this.options.container);\n\t\tthis._rootSize = 0;\n\t\tthis._containerPosition = 0;\n\t\tthis._style = style[this.options.horizontal ? \"horizontal\" : \"vertical\"];\n\t\tthis.resize();\n\t}\n\t/**\n\t * As the browser is resized, the gaps between the root and the container and the size of the items are updated.\n\t * @ko 브라우저의 크기가 변경됨으로 써 root와 container의 간격과 아이템들의 크기를 갱신한다.\n\t * @method eg.Parallax#resize\n\t * @param {Array} [items = []] Items to apply parallax. It does not apply if it is not in visible range. parallax를 적용할 아이템들. 가시거리에 존재하지 않으면 적용이 안된다.\n\t * @return {eg.Parallax} An instance of a module itself모듈 자신의 인스턴스\n\t * @example\n ```js\n window.addEventListener(\"resize\", function (e) {\n\tparallax.resize(items);\n });\n ```\n\t */\n\tpublic resize(items: IInfiniteGridItem[] = []) {\n\t\tconst root = this._root;\n\t\tconst container = this._container;\n\t\tconst positionName = this._style.position;\n\t\tconst sizeName = this._style.cammelSize;\n\n\t\tif (!container || root === container) {\n\t\t\tthis._containerPosition = 0;\n\t\t} else {\n\t\t\tconst rootRect = (isWindow(root) ? document.body : root).getBoundingClientRect();\n\t\t\tconst containertRect = container.getBoundingClientRect();\n\n\t\t\tthis._containerPosition = containertRect[positionName] - rootRect[positionName];\n\t\t}\n\t\tthis._rootSize = isWindow(root) ?\n\t\t\twindow[`inner${sizeName}` as InnerSizeType] ||\n\t\t\tdocument.documentElement[`client${sizeName}` as ClientSizeType] :\n\t\t\troot[`client${sizeName}` as ClientSizeType];\n\n\t\tif (isMobile && isWindow(root)) {\n\t\t\tconst bodyWidth = document.body.offsetWidth || document.documentElement.offsetWidth;\n\t\t\tconst windowWidth = window.innerWidth;\n\n\t\t\tthis._rootSize = this._rootSize / (bodyWidth / windowWidth);\n\t\t}\n\t\titems.forEach(item => {\n\t\t\tthis._checkParallaxItem(item.el);\n\t\t});\n\n\t\treturn this;\n\t}\n\t/**\n\t * Scrolls the image in the item by a parallax.\n\t * @ko 스크롤하면 아이템안의 이미지를 시차적용시킨다.\n\t * @method eg.Parallax#refresh\n\t * @param {Array} [items = []] Items to apply parallax. It does not apply if it is not in visible range. parallax를 적용할 아이템들. 가시거리에 존재하지 않으면 적용이 안된다.\n\t * @param {Number} [scrollPositionStart = 0] The scroll position.\n\t * @return {eg.Parallax} An instance of a module itself모듈 자신의 인스턴스\n\t * @example\n ```js\n document.body.addEventListener(\"scroll\", function (e) {\n\tparallax.refresh(items, e.scrollTop);\n });\n ```\n\t */\n\tpublic refresh(items: IInfiniteGridItem[] = [], scrollPositionStart = 0) {\n\t\tconst styleNames = this._style;\n\t\tconst positionName = styleNames.position;\n\t\tconst coordinateName = styleNames.coordinate;\n\t\tconst sizeName = styleNames.size;\n\t\tconst options = this.options;\n\t\tconst { strength, center, range, align } = options;\n\t\tconst rootSize = this._rootSize;\n\t\tconst scrollPositionEnd = scrollPositionStart + rootSize;\n\t\tconst containerPosition = this._containerPosition;\n\n\t\titems.forEach(item => {\n\t\t\tif (!item.rect || !item.size || !item.el) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst position = containerPosition + item.rect[positionName];\n\t\t\tconst itemSize = item.rect[sizeName] || item.size[sizeName];\n\n\t\t\t// check item is in container.\n\t\t\tif (scrollPositionStart > position + itemSize ||\n\t\t\t\tscrollPositionEnd < position) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst el = item.el;\n\n\t\t\tif (!el.__IMAGE__) {\n\t\t\t\tthis._checkParallaxItem(el);\n\t\t\t}\n\t\t\tif (el.__IMAGE__ === -1) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst imageElement = el.__IMAGE__;\n\t\t\tconst boxElement = el.__BOX__;\n\t\t\tconst boxSize = boxElement.__SIZE__;\n\t\t\tconst imageSize = imageElement.__SIZE__;\n\n\t\t\t// no parallax\n\t\t\tif (boxSize >= imageSize) {\n\t\t\t\t// remove transform style\n\t\t\t\timageElement.style[TRANSFORM] = \"\";\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// if area's position is center, ratio is 0.\n\t\t\t// if area is hidden at the top, ratio is 1.\n\t\t\t// if area is hidden at the bottom, ratio is -1.\n\t\t\tconst imagePosition = position + boxSize / 2;\n\t\t\tlet ratio = (scrollPositionStart + rootSize / 2 -\n\t\t\t\t(rootSize + boxSize) / 2 * center - imagePosition) /\n\t\t\t\t(rootSize + boxSize) * 2 * strength;\n\n\t\t\t// if ratio is out of the range of -1 and 1, show empty space.\n\t\t\tratio = Math.max(Math.min(ratio, range[1]), range[0]);\n\n\t\t\t// dist is the position when thumnail's image is centered.\n\t\t\tconst dist = (boxSize - imageSize) / 2;\n\t\t\tlet translate = dist * (1 - ratio);\n\n\t\t\tif (align === CENTER) {\n\t\t\t\ttranslate -= dist;\n\t\t\t}\n\n\t\t\timageElement.__TRANSLATE__ = translate;\n\t\t\timageElement.__RATIO__ = ratio;\n\t\t\timageElement.style[TRANSFORM] = `translate${coordinateName}(${translate}px)`;\n\t\t});\n\t\treturn this;\n\t}\n\tprivate _checkParallaxItem(element: IInfiniteGridItemElement) {\n\t\tif (!element) {\n\t\t\treturn;\n\t\t}\n\t\tconst selector = this.options.selector;\n\n\t\tif (!element.__IMAGE__) {\n\t\t\tconst img = element.querySelector(selector);\n\n\t\t\telement.__IMAGE__ = img || -1;\n\t\t\tif (element.__IMAGE__ === -1) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telement.__BOX__ = img.parentNode as IInfiniteGridItemElement;\n\t\t}\n\t\tif (element.__IMAGE__ === -1) {\n\t\t\treturn;\n\t\t}\n\t\tconst sizeName = this._style.cammelSize;\n\n\t\telement.__IMAGE__.__SIZE__ = element.__IMAGE__[`offset${sizeName}` as OffsetSizeType];\n\t\telement.__BOX__.__SIZE__ = element.__BOX__[`offset${sizeName}` as OffsetSizeType];\n\t}\n}\n\nexport default Parallax;\n"],"names":["win","document","window","navigator","userAgent","ua","SUPPORT_ADDEVENTLISTENER","agent","supportsPassiveOption","Object","defineProperty","addEventListener","get","e","test","toLowerCase","isMobile","ALIGN","webkit","exec","TRANSFORM","parseInt","param","multi","el","isWindow","jQuery","constructor","prototype","jquery","toArray","$","Array","isArray","map","v","length","undefined","nodeName","nodeType","match","dummy","createElement","innerHTML","childNodes","querySelectorAll","nodes","array","i","len","push","style","vertical","position","size","cammelSize","coordinate","horizontal","START","CENTER","root","options","target","_i","sources","forEach","source","key","assign","container","selector","strength","center","range","align","_root","_container","this","_rootSize","_containerPosition","_style","resize","items","positionName","sizeName","rootRect","body","getBoundingClientRect","containertRect","documentElement","bodyWidth","offsetWidth","windowWidth","innerWidth","item","_this","_checkParallaxItem","scrollPositionStart","styleNames","coordinateName","rootSize","scrollPositionEnd","containerPosition","rect","__IMAGE__","imageElement","boxSize","__BOX__","__SIZE__","imageSize","ratio","dist","translate","Math","max","min","__TRANSLATE__","__RATIO__","element","img","querySelector","parentNode"],"mappings":"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"}