UNPKG

rfx-parallax

Version:
1 lines 38.8 kB
{"version":3,"file":"rfx-parallax.mjs","sources":["../../../projects/rfx-parallax/src/lib/services/resize-event.service.ts","../../../projects/rfx-parallax/src/lib/services/scroll-event.service.ts","../../../projects/rfx-parallax/src/lib/services/rfx-parallax.service.ts","../../../projects/rfx-parallax/src/lib/animations/visibility.animation.ts","../../../projects/rfx-parallax/src/lib/directives/will-change.directive.ts","../../../projects/rfx-parallax/src/lib/components/rfx-parallax/rfx-parallax.component.ts","../../../projects/rfx-parallax/src/lib/components/rfx-parallax/rfx-parallax.component.html","../../../projects/rfx-parallax/src/lib/rfx-parallax.module.ts","../../../projects/rfx-parallax/src/public-api.ts","../../../projects/rfx-parallax/src/rfx-parallax.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\r\nimport { Inject, Injectable, OnDestroy, PLATFORM_ID } from '@angular/core';\r\nimport { Observable, Subject } from 'rxjs';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ResizeEventService implements OnDestroy {\r\n /**\r\n * Subscribe to window resize changes.\r\n * @type {Subject<undefined>}\r\n */\r\n private subjectResize: Subject<undefined>;\r\n\r\n /**\r\n * Window resize listener.\r\n * @type {EventListenerOrEventListenerObject}\r\n */\r\n private resizeEvent: EventListenerOrEventListenerObject;\r\n\r\n private isBrowser: boolean;\r\n\r\n constructor(\r\n @Inject(PLATFORM_ID) private platformId: Object\r\n ) {\r\n this.subjectResize = new Subject<undefined>();\r\n this.resizeEvent = this.onResizeEvent.bind(this);\r\n this.isBrowser = isPlatformBrowser(platformId);\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this.destroyListener();\r\n }\r\n\r\n /**\r\n * Create window resize listener.\r\n */\r\n public createListener(): void {\r\n if (this.isBrowser) {\r\n window.addEventListener('resize', this.resizeEvent, { passive: true });\r\n }\r\n }\r\n\r\n /**\r\n * Destroy window resize listener.\r\n */\r\n public destroyListener(): void {\r\n if (this.isBrowser) {\r\n window.removeEventListener('resize', this.resizeEvent);\r\n }\r\n }\r\n\r\n /**\r\n * Trigger window resize event.\r\n */\r\n private onResizeEvent(): void {\r\n this.subjectResize.next(undefined);\r\n }\r\n\r\n /**\r\n * Get window resize event.\r\n * @return {Observable<undefined>} - Window resize event.\r\n */\r\n public getResize(): Observable<undefined> {\r\n return this.subjectResize.asObservable();\r\n }\r\n}\r\n","import { Injectable, OnDestroy } from '@angular/core';\r\nimport { BehaviorSubject, Observable } from 'rxjs';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ScrollEventService implements OnDestroy {\r\n /**\r\n * Subscribe to body scroll changes.\r\n * @type {BehaviorSubject<number>}\r\n */\r\n private subjectScroll: BehaviorSubject<number>;\r\n\r\n /**\r\n * Mouse scroll listener.\r\n * @type {EventListenerOrEventListenerObject}\r\n */\r\n private mouseScrollEvent: EventListenerOrEventListenerObject;\r\n\r\n /**\r\n * Current element with scroll event.\r\n * @type {HTMLElement | Document | undefined}\r\n */\r\n private element: HTMLElement | Document | undefined;\r\n\r\n constructor() {\r\n this.subjectScroll = new BehaviorSubject<number>(0);\r\n this.mouseScrollEvent = this.onMouseScroll.bind(this);\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this.destroyListener();\r\n }\r\n\r\n /**\r\n * Create mouse scroll listener.\r\n * @param {HTMLElement} element - Element with scroll event.\r\n */\r\n public createListener(element: HTMLElement | Document): void {\r\n this.element = element;\r\n this.element.addEventListener('scroll', this.mouseScrollEvent, { passive: true });\r\n }\r\n\r\n /**\r\n * Destroy mouse scroll listener.\r\n */\r\n public destroyListener(): void {\r\n this.element?.removeEventListener('scroll', this.mouseScrollEvent);\r\n this.element = undefined;\r\n }\r\n\r\n /**\r\n * Trigger mouse scroll event.\r\n * @param {number} event - Mouse scroll event.\r\n */\r\n private onMouseScroll(event: Event): void {\r\n const target: HTMLElement = event.target instanceof Document ? event.target.documentElement : (event.target as HTMLElement);\r\n this.subjectScroll.next(target.scrollTop);\r\n }\r\n\r\n /**\r\n * Get body scroll event.\r\n * @return {Observable<number>} - Body scroll event.\r\n */\r\n public getMouseScroll(): Observable<number> {\r\n return this.subjectScroll.asObservable();\r\n }\r\n\r\n /**\r\n * Get body scroll current value.\r\n * @return {number} - Body scroll value.\r\n */\r\n public getMouseScrollValue(): number {\r\n return this.subjectScroll.value;\r\n }\r\n}\r\n","import { isPlatformBrowser } from '@angular/common';\r\nimport { Inject, Injectable, PLATFORM_ID } from '@angular/core';\r\nimport { ResizeEventService } from './resize-event.service';\r\nimport { ScrollEventService } from './scroll-event.service';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class RfxParallaxService {\r\n private isBrowser: boolean;\r\n\r\n constructor(\r\n private resizeEventService: ResizeEventService,\r\n private scrollEventService: ScrollEventService,\r\n @Inject(PLATFORM_ID) private platformId: Object\r\n ) {\r\n this.isBrowser = isPlatformBrowser(this.platformId);\r\n }\r\n\r\n /**\r\n * Start element scroll event, window resize event and element resize event listeners\r\n * @param element main element with scroll property\r\n */\r\n public initListeners(element?: HTMLElement | Document): void {\r\n if (this.isBrowser) {\r\n this.resizeEventService.createListener();\r\n this.scrollEventService.createListener(element ?? document);\r\n }\r\n }\r\n}\r\n","import { animate, AnimationTriggerMetadata, state, style, transition, trigger } from \"@angular/animations\";\r\n\r\nexport const visibilityAnimation: AnimationTriggerMetadata[] = [\r\n trigger('visibility', [\r\n state('true', style({\r\n opacity: 1\r\n })),\r\n state('false', style({\r\n opacity: 0,\r\n }))\r\n // transition('true <=> false', [\r\n // animate('{{ transitionDurationMs }}ms {{ transitionDelayMs }}ms {{ transitionTimingFunction }}')\r\n // ], { params: { transitionDurationMs: 0, transitionDelayMs: 0, transitionTimingFunction: 'ease' }})\r\n ])\r\n];\r\n","import { Directive, ElementRef, Input, OnChanges, OnDestroy, OnInit, Renderer2, SimpleChanges } from '@angular/core';\r\nimport { ScrollEventService } from '../services';\r\nimport { SectionAreaModel } from '../models';\r\nimport { Subscription } from 'rxjs';\r\n\r\n@Directive({\r\n selector: '[libWillChange]'\r\n})\r\nexport class WillChangeDirective implements OnInit, OnChanges, OnDestroy {\r\n /**\r\n * Area where element has will-change property.\r\n * Default is window height / 4 * 6.\r\n * @type {number}\r\n */\r\n @Input()\r\n public triggerArea: number;\r\n\r\n /**\r\n * If disabled, element will have will-change\r\n * property set to 'auto'.\r\n * @type {boolean}\r\n */\r\n @Input()\r\n public isDisabled: boolean;\r\n\r\n /**\r\n * Range in pixels where the element has\r\n * will-change property.\r\n * @type {SectionAreaModel | undefined}\r\n */\r\n private willChangeArea: SectionAreaModel | undefined;\r\n\r\n /**\r\n * Element will change value.\r\n * @type {boolean}\r\n */\r\n private willChange: boolean;\r\n\r\n /**\r\n * Subscription to scroll event.\r\n * @type {Subscription | undefined}\r\n */\r\n private scrollEventListener: Subscription | undefined;\r\n\r\n constructor(\r\n private htmlElement: ElementRef,\r\n private renderer: Renderer2,\r\n private scrollEventService: ScrollEventService\r\n ) {\r\n this.triggerArea = typeof window !== 'undefined' ? window.innerHeight / 4 * 6 : 0;\r\n this.isDisabled = false;\r\n this.willChange = true;\r\n }\r\n\r\n public ngOnInit(): void {\r\n if (!this.isDisabled) {\r\n this.willChangeArea = this.getWillChangeArea();\r\n this.createListener();\r\n }\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this.destroyListener();\r\n }\r\n\r\n /**\r\n * Create listener for scroll event.\r\n */\r\n private createListener(): void {\r\n this.scrollEventListener = this.scrollEventService.getMouseScroll().subscribe(\r\n (scroll: number) => this.checkWillChange(scroll)\r\n );\r\n }\r\n\r\n /**\r\n * Destroy scroll event listener.\r\n */\r\n private destroyListener(): void {\r\n this.scrollEventListener?.unsubscribe();\r\n }\r\n\r\n /**\r\n * Refresh will-change area if some properties changed.\r\n * @param {SimpleChanges} changes - Changes.\r\n */\r\n public ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['isDisabled'] && (changes['isDisabled'].currentValue !== undefined) && !changes['isDisabled'].firstChange) {\r\n this.destroyListener();\r\n return;\r\n }\r\n\r\n if (changes['triggerArea'] && (changes['triggerArea'].currentValue !== undefined) && !changes['triggerArea'].firstChange && !this.isDisabled) {\r\n const scroll: number = this.scrollEventService.getMouseScrollValue();\r\n this.willChangeArea = this.getWillChangeArea();\r\n this.checkWillChange(scroll);\r\n }\r\n }\r\n\r\n /**\r\n * Check will-change property and\r\n * update if needed.\r\n * @param {number} scroll - Scroll position.\r\n */\r\n private checkWillChange(scroll: number): void {\r\n if (this.willChangeArea) {\r\n const isElementInArea: boolean = this.isElementInArea(scroll, this.willChangeArea);\r\n\r\n if (isElementInArea !== this.willChange) {\r\n this.setWillChange(isElementInArea);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Check if element is in will-change area.\r\n * @param {number} scroll - Scroll position.\r\n * @param {SectionAreaModel} willChangeArea - Will-change area.\r\n * @returns {boolean} - Is element in will-change area.\r\n */\r\n private isElementInArea(scroll: number, willChangeArea: SectionAreaModel): boolean {\r\n return scroll >= willChangeArea.top && scroll <= willChangeArea.bottom;\r\n }\r\n\r\n /**\r\n * Calculate area where element is probably going to be animated soon.\r\n * @returns {number} - Will-change area.\r\n */\r\n private getWillChangeArea(): SectionAreaModel {\r\n const elementRect: DOMRect = this.htmlElement.nativeElement.getBoundingClientRect();\r\n const scroll: number = this.scrollEventService.getMouseScrollValue();\r\n const elementTop: number = elementRect.top + scroll;\r\n const areaTop: number = elementTop - this.triggerArea;\r\n const areaBottom: number = elementTop + this.triggerArea;\r\n return { top: areaTop, bottom: areaBottom };\r\n }\r\n\r\n /**\r\n * Set element will-change property.\r\n * @param {boolean} willChange - will-change enabled or disabled.\r\n */\r\n private setWillChange(willChange: boolean): void {\r\n this.willChange = willChange;\r\n this.renderer.setStyle(\r\n this.htmlElement.nativeElement,\r\n 'will-change',\r\n willChange ? 'transform' : 'auto'\r\n );\r\n }\r\n}\r\n","import { Component, ElementRef, Inject, Input, OnChanges, OnInit, PLATFORM_ID, Renderer2, SimpleChange, SimpleChanges } from '@angular/core';\r\nimport { Subscription } from 'rxjs';\r\nimport { ResizeEventService, ScrollEventService } from '../../services';\r\nimport { ParallaxBoundariesModel } from '../../models';\r\nimport { visibilityAnimation } from '../../animations';\r\nimport { isPlatformBrowser } from '@angular/common';\r\n\r\n@Component({\r\n selector: '[libRfxParallax]',\r\n templateUrl: './rfx-parallax.component.html',\r\n styleUrls: ['./rfx-parallax.component.less'],\r\n animations: [\r\n visibilityAnimation\r\n ]\r\n})\r\nexport class RfxParallaxComponent implements OnInit, OnChanges {\r\n /**\r\n * Image url.\r\n * Can be http(s) or relative path.\r\n * TODO: Add support for fallback.\r\n * @type {string}\r\n */\r\n @Input()\r\n public imageUrl: string | undefined;\r\n\r\n /**\r\n * Image alt attribute.\r\n * @type {string}\r\n */\r\n @Input()\r\n public imageAlt: string | undefined;\r\n\r\n /**\r\n * Percentage of image scrolling.\r\n * e.g. 40% will scroll 40% of the image.\r\n * Default is 40.\r\n * @type {number}\r\n */\r\n @Input()\r\n public parallaxPercentage: number;\r\n\r\n /**\r\n * Image view position in percentage.\r\n * e.g. 50% will show centered image in container.\r\n * Default is 50.\r\n * @type {number}\r\n */\r\n @Input()\r\n public positionPercentage: number;\r\n\r\n /**\r\n * Image z-index property.\r\n * Default is -1.\r\n * @type {number}\r\n */\r\n @Input()\r\n public imageZIndex: number;\r\n\r\n /**\r\n * Show or hide image overflow on container.\r\n * Default is false (hide).\r\n * @type {boolean}\r\n */\r\n @Input()\r\n public visibleOverflow: boolean;\r\n\r\n /**\r\n * Disable image parallax effect and\r\n * restore default image position.\r\n * Useful on low performance devices.\r\n * @type {boolean}\r\n */\r\n @Input()\r\n public isDisabled: boolean;\r\n\r\n /**\r\n * Force image to be 100% of container width.\r\n * @type {boolean}\r\n */\r\n @Input()\r\n public forceFullWidth: boolean;\r\n\r\n /**\r\n * Subscription to scroll event.\r\n * @type {Subscription | undefined}\r\n */\r\n private scrollEventListener: Subscription | undefined;\r\n\r\n /**\r\n * Subscription to resize event.\r\n * @type {Subscription | undefined}\r\n */\r\n private resizeEventListener: Subscription | undefined;\r\n\r\n /**\r\n * Parallaxed image boundaries.\r\n * @type {ParallaxBoundariesModel | undefined}\r\n */\r\n private parallaxBoundaries: ParallaxBoundariesModel | undefined;\r\n\r\n /**\r\n * Image to be parallaxed.\r\n * @type {HTMLImageElement | undefined}\r\n */\r\n private image: HTMLImageElement | undefined;\r\n\r\n /**\r\n * Image left position.\r\n * We save this value and reduce overhead of\r\n * calculating it every time on scroll.\r\n * @type {number}\r\n */\r\n private imageLeftPx: number;\r\n\r\n /**\r\n * Is image loaded.\r\n * @type {boolean}\r\n */\r\n public isLoaded: boolean;\r\n\r\n /**\r\n * Is platform browser.\r\n * False for example when using SSR.\r\n * @type {boolean}\r\n */\r\n public isBrowser: boolean;\r\n\r\n\r\n constructor(\r\n private htmlElement: ElementRef,\r\n private renderer: Renderer2,\r\n private scrollEventService: ScrollEventService,\r\n private resizeEventService: ResizeEventService,\r\n @Inject(PLATFORM_ID) private platformId: Object\r\n ) {\r\n this.parallaxPercentage = 40;\r\n this.positionPercentage = 50;\r\n this.imageZIndex = -1;\r\n this.isDisabled = false;\r\n this.visibleOverflow = false;\r\n this.imageLeftPx = 0;\r\n this.isLoaded = false;\r\n this.forceFullWidth = false;\r\n this.isBrowser = isPlatformBrowser(this.platformId);\r\n }\r\n\r\n /**\r\n * Set container position and overflow.\r\n * If parallax is not disabled, create listeners.\r\n */\r\n public ngOnInit(): void {\r\n if (this.isBrowser) {\r\n this.setContainerPosition(this.htmlElement.nativeElement);\r\n this.setContainerOverflow(this.htmlElement.nativeElement, this.visibleOverflow);\r\n\r\n if (!this.isDisabled) {\r\n this.createListeners();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Update parallax values when some properies changed.\r\n * - isDisabled change, enable or disable parallax and refresh image properties.\r\n * - visibleOverflow change, show or hide image overflow on container without refresh.\r\n * - imagerUrl, parallaxPercentage or positionPercentage change, refresh image properties.\r\n * @param {SimpleChanges} changes - SimpleChanges object.\r\n */\r\n public ngOnChanges(changes: SimpleChanges): void {\r\n if (this.isBrowser) {\r\n if (this.hasValueChanged(changes['isDisabled'], true)) {\r\n this.destroyListeners();\r\n } else if (this.hasValueChanged(changes['isDisabled'], false)) {\r\n this.createListeners();\r\n }\r\n\r\n if (this.hasValueChanged(changes['visibleOverflow'])) {\r\n this.setContainerOverflow(this.htmlElement.nativeElement, changes['visibleOverflow'].currentValue);\r\n }\r\n\r\n if (this.image && ((\r\n this.hasValueChanged(changes['imageUrl']) ||\r\n this.hasValueChanged(changes['parallaxPercentage']) ||\r\n this.hasValueChanged(changes['positionPercentage'])) ||\r\n this.hasValueChanged(changes['isDisabled']) ||\r\n this.hasValueChanged(changes['forceFullWidth']))) {\r\n this.setImageProperties(this.image);\r\n }\r\n }\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this.destroyListeners();\r\n }\r\n\r\n /**\r\n * Check if SimpleChange value has changed.\r\n * Eventually check if value corresponds to a new value.\r\n * @param {SimpleChange} change - SimpleChange object.\r\n * @param {any} newValue - New value.\r\n * @returns {boolean} - true if value has changed.\r\n */\r\n private hasValueChanged(change: SimpleChange, newValue: any = change?.currentValue): boolean {\r\n return change?.firstChange === false && change?.currentValue !== undefined && change?.currentValue === newValue;\r\n }\r\n\r\n /**\r\n * Destroy all listeners.\r\n */\r\n private destroyListeners(): void {\r\n this.scrollEventListener?.unsubscribe();\r\n this.resizeEventListener?.unsubscribe();\r\n }\r\n\r\n /**\r\n * Listen to scroll and resize events.\r\n * Destroy alreay existing listeners.\r\n */\r\n private createListeners(): void {\r\n this.destroyListeners();\r\n\r\n this.scrollEventListener = this.scrollEventService.getMouseScroll().subscribe(\r\n (scroll: number) => this.onMouseScroll(scroll)\r\n );\r\n\r\n this.resizeEventListener = this.resizeEventService.getResize().subscribe(\r\n () => this.onResize()\r\n );\r\n }\r\n\r\n /**\r\n * On mouse scroll event recalculate and change\r\n * parallaxed image position.\r\n * @param {number} scroll - Scroll value.\r\n */\r\n private onMouseScroll(scroll: number): void {\r\n if (this.parallaxBoundaries && this.image) {\r\n const topPx: number = this.getImageTop(scroll, this.parallaxBoundaries);\r\n this.setImageTransform(this.image, this.imageLeftPx, topPx);\r\n }\r\n }\r\n\r\n /**\r\n * On window resize event reload parallax properties.\r\n */\r\n private onResize(): void {\r\n if (this.image) {\r\n this.setImageProperties(this.image);\r\n }\r\n }\r\n\r\n /**\r\n * Set image object and loading status.\r\n * Set image properties after image is fully loaded\r\n * but only if platform is browser.\r\n * @param {Event} event - Image loaded event.\r\n */\r\n public onImageLoaded(event: Event): void {\r\n this.image = event.target as HTMLImageElement;\r\n\r\n if (this.isBrowser) {\r\n this.setImageProperties(this.image);\r\n }\r\n\r\n this.isLoaded = true;\r\n }\r\n\r\n /**\r\n * Set image properties needed for parallax effect.\r\n * @param {HTMLImageElement} image - Image to be parallaxed.\r\n */\r\n private setImageProperties(image: HTMLImageElement): void {\r\n const scrollTop: number = this.scrollEventService.getMouseScrollValue();\r\n\r\n this.setImageSize(\r\n image,\r\n this.htmlElement.nativeElement.clientWidth,\r\n this.htmlElement.nativeElement.clientHeight,\r\n this.parallaxPercentage,\r\n this.isDisabled,\r\n this.forceFullWidth\r\n );\r\n\r\n this.parallaxBoundaries = this.getParallaxBoundaries(\r\n scrollTop,\r\n this.htmlElement.nativeElement,\r\n image.height,\r\n this.parallaxPercentage\r\n );\r\n\r\n this.imageLeftPx = this.getImageLeft(\r\n this.htmlElement.nativeElement.clientWidth,\r\n image.width,\r\n this.positionPercentage\r\n );\r\n\r\n const topPx: number = this.isDisabled ?\r\n this.getDisabledImageTop(this.parallaxBoundaries) :\r\n this.getImageTop(scrollTop, this.parallaxBoundaries);\r\n\r\n this.setImageTransform(image, this.imageLeftPx, topPx);\r\n }\r\n\r\n /**\r\n * Set container position to relative\r\n * if image is not already in relative or absolute position.\r\n * @param {HTMLElement} container\r\n */\r\n private setContainerPosition(container: HTMLElement): void {\r\n const position: string = getComputedStyle(container).position;\r\n if (position !== 'relative' && position !== 'absolute') {\r\n this.renderer.setStyle(container, 'position', 'relative');\r\n }\r\n }\r\n\r\n /**\r\n * Set container overflow.\r\n * @param {HTMLElement} container - Container element.\r\n * @param {boolean} isOverflowVisible - true to show container overflow.\r\n */\r\n private setContainerOverflow(container: HTMLElement, isOverflowVisible: boolean): void {\r\n this.renderer.setStyle(container, 'overflow', isOverflowVisible ? 'visible' : 'hidden');\r\n }\r\n\r\n /**\r\n * Set image size based on container size,\r\n * parallax percentage and disabled state.\r\n * @param {HTMLImageElement} image - Image element.\r\n * @param {number} containerWidth - Container width.\r\n * @param {number} containerHeight - Container height.\r\n * @param {number} parallaxPercentage - Parallax percentage.\r\n * @param {boolean} isDisabled - true to disable parallax effect.\r\n * @param {boolean} forceFullWidth - true to force image size to container width.\r\n */\r\n private setImageSize(\r\n image: HTMLImageElement,\r\n containerWidth: number,\r\n containerHeight: number,\r\n parallaxPercentage: number,\r\n isDisabled: boolean,\r\n forceFullWidth: boolean\r\n ): void {\r\n if (forceFullWidth) {\r\n this.renderer.setAttribute(image, 'width', `${containerWidth}px`);\r\n this.renderer.setAttribute(image, 'height', `auto`);\r\n } else {\r\n const minimumHeight: number = (containerHeight * (100 + (isDisabled ? 0 : parallaxPercentage))) / 100;\r\n const ratio: number = image.naturalHeight / image.naturalWidth;\r\n const minimumRatio: number = minimumHeight / containerWidth;\r\n\r\n if (ratio > minimumRatio) {\r\n this.renderer.setAttribute(image, 'width', `${containerWidth}px`);\r\n this.renderer.setAttribute(image, 'height', `auto`);\r\n } else {\r\n this.renderer.setAttribute(image, 'width', `auto`);\r\n this.renderer.setAttribute(image, 'height', `${minimumHeight}px`);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get parallax boundaries. This data is used\r\n * to calculate parallax movement.\r\n * @param {number} scrollTop - Scroll top.\r\n * @param {HTMLElement} container - Container element.\r\n * @param {number} imageHeight - Image height.\r\n * @param {number} parallaxPercentage - Parallax percentage.\r\n * @return {ParallaxBoundariesModel} - Parallax boundaries.\r\n */\r\n private getParallaxBoundaries(scrollTop: number, container: HTMLElement, imageHeight: number, parallaxPercentage: number): ParallaxBoundariesModel {\r\n const elementTop: number = container.getBoundingClientRect().top + scrollTop;\r\n const usablePixels: number = container.clientHeight / 100 * parallaxPercentage;\r\n const unusablePixels: number = imageHeight - container.clientHeight - usablePixels;\r\n const startPoint: number = elementTop - usablePixels - window.innerHeight;\r\n const endPoint = elementTop + container.clientHeight + usablePixels;\r\n const totalPixels = endPoint - startPoint;\r\n return { startPoint, endPoint, totalPixels, usablePixels, unusablePixels };\r\n }\r\n\r\n /**\r\n * Get image left position.\r\n * @param {number} containerWidth - Container width.\r\n * @param {number} imageWidth - Image width.\r\n * @param {number} positionPercentage - Position percentage.\r\n * @return {number} - Image left position.\r\n */\r\n private getImageLeft(containerWidth: number, imageWidth: number, positionPercentage: number): number {\r\n return (containerWidth - imageWidth) / 100 * positionPercentage;\r\n }\r\n\r\n /**\r\n * Get image top position.\r\n * @param {number} scrollTop - Scroll top.\r\n * @param {ParallaxBoundariesModel} boundaries - Parallax boundaries.\r\n * @return {number} - Image top position.\r\n */\r\n private getImageTop(scrollTop: number, boundaries: ParallaxBoundariesModel): number {\r\n const area: number = Math.max(0, Math.min(scrollTop - boundaries.startPoint, boundaries.totalPixels));\r\n const areaPercentage: number = 100 / boundaries.totalPixels * area;\r\n return -boundaries.usablePixels * (1 - areaPercentage / 100) - boundaries.unusablePixels / 2;\r\n }\r\n\r\n /**\r\n * Get disabled image top position.\r\n * @param {number} boundaries - Parallax boundaries.\r\n * @return {number} - Image top position.\r\n */\r\n private getDisabledImageTop(boundaries: ParallaxBoundariesModel): number {\r\n return (-boundaries.usablePixels - boundaries.unusablePixels) / 2\r\n }\r\n\r\n /**\r\n * Set image transform properties.\r\n * @param {HTMLImageElement} image - Image element.\r\n * @param {number} leftPx - Image left position.\r\n * @param {number} topPx - Image top position.\r\n */\r\n private setImageTransform(image: HTMLImageElement, leftPx: number, topPx: number): void {\r\n const newTranslate: string = `translate(${leftPx.toFixed(1)}px, ${topPx.toFixed(1)}px)`;\r\n\r\n if (image.style.transform !== newTranslate) {\r\n this.renderer.setStyle(image, 'transform', newTranslate);\r\n }\r\n }\r\n}\r\n","<img\r\n [alt]=\"imageAlt ?? ''\"\r\n [@visibility]=\"isLoaded\"\r\n libWillChange\r\n [isDisabled]=\"isDisabled || !isBrowser\"\r\n class=\"rfx-image\"\r\n [src]=\"imageUrl\"\r\n [style.zIndex]=\"imageZIndex\"\r\n (load)=\"onImageLoaded($event)\" />\r\n\r\n<ng-content></ng-content>\r\n","import { NgModule } from '@angular/core';\r\nimport { RfxParallaxComponent } from './components/rfx-parallax/rfx-parallax.component';\r\nimport { WillChangeDirective } from './directives/will-change.directive';\r\n\r\n@NgModule({\r\n declarations: [\r\n RfxParallaxComponent,\r\n WillChangeDirective\r\n ],\r\n imports: [],\r\n exports: [\r\n RfxParallaxComponent\r\n ]\r\n})\r\nexport class RfxParallaxModule { }\r\n","/*\r\n * Public API Surface of rfx-parallax\r\n */\r\n\r\nexport * from './lib/services/rfx-parallax.service';\r\nexport * from './lib/components/rfx-parallax/rfx-parallax.component';\r\nexport * from './lib/rfx-parallax.module';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}