UNPKG

@yoozly/ngx-parallax

Version:

Use parallax effect with Angular 19 compatible universal (standalone and ngModule)

324 lines (316 loc) 12.3 kB
import * as i0 from '@angular/core'; import { PLATFORM_ID, Inject, Injectable, Input, Directive, NgModule } from '@angular/core'; import { Subject, of, fromEvent } from 'rxjs'; import { takeUntil, filter, map, mergeMap, debounceTime } from 'rxjs/operators'; import { isPlatformBrowser } from '@angular/common'; class BrowserWindowRef { platformId; constructor(platformId) { this.platformId = platformId; } get nativeWindow() { if (isPlatformBrowser(this.platformId)) { return this.windowRef(); } return false; } windowRef() { // return the global native browser window object return window; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BrowserWindowRef, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BrowserWindowRef, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BrowserWindowRef, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }] }); class ParallaxDirective { hostElement; renderer; wr; speed = 30; axe = 'y'; property = 'transform'; propertyValue = 'translate3d'; active = true; inViewport = true; observer; element; initialPosition; componentDestroy$ = new Subject(); windowScroll$; windowResize$; constructor(hostElement, renderer, wr) { this.hostElement = hostElement; this.renderer = renderer; this.wr = wr; } ngAfterViewInit() { this.element = this.hostElement.nativeElement; if (this.element && this.wr.nativeWindow && !this.observer) { this.initParallax(); } } initParallax() { this.observer = this.createObserver(0); this.observer.observe(this.element); const parallax$ = of('').pipe(takeUntil(this.componentDestroy$), filter(() => this.active && this.inViewport), map(() => { const coef = this.calculateCoef(); this.renderParallax(coef); return coef; })); this.windowScroll$ = fromEvent(this.wr.nativeWindow, 'scroll').pipe(mergeMap(() => parallax$)); this.windowResize$ = fromEvent(this.wr.nativeWindow, 'resize').pipe(debounceTime(500), mergeMap(() => parallax$)); } startParallax() { this.inViewport = true; if (this.wr.nativeWindow && this.initialPosition === undefined) { this.initialPosition = this.wr.nativeWindow.pageYOffset; this.windowScroll$.subscribe(); this.windowResize$.subscribe(); } } destroyParallax() { this.inViewport = false; } calculateCoef() { return ((this.wr.nativeWindow.pageYOffset - this.initialPosition) * (this.speed / 100)); } renderParallax(coef) { this.renderer.setStyle(this.element, this.property, this.getPropertyValue(coef)); } getPropertyValue(coef) { let result = `${coef}px`; if (this.property === 'transform') { switch (this.propertyValue) { case 'translate3d': result = `translate3d(${this.getAxe(coef)})`; break; case 'scale': result = `scale(${coef})`; break; case 'rotate': result = `rotate(${coef}deg)`; break; } } switch (this.property) { case 'opacity': result = `${coef}`; break; } return result; } getAxe(coef) { let axe = [0, coef, 0]; if (this.axe === 'x') { axe = [coef, 0, 0]; } else if (this.axe === 'z') { axe = [0, 0, coef]; } return `${axe[0]}px, ${axe[1]}px, ${axe[2]}px`; } createObserver(pourcent) { const options = { rootMargin: '0px', threshold: pourcent / 100 }; const isIntersecting = (entry) => entry.isIntersecting || entry.intersectionRatio > 0; return new IntersectionObserver((entries, observer) => { entries.forEach((entry) => { if (isIntersecting(entry)) { this.startParallax(); } else { this.destroyParallax(); } }); }, options); } ngOnDestroy() { this.componentDestroy$.next(false); this.componentDestroy$.complete(); if (this.wr.nativeWindow) { this.observer.disconnect(); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ParallaxDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: BrowserWindowRef }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.7", type: ParallaxDirective, isStandalone: false, selector: "[ngx-parallax]", inputs: { speed: "speed", axe: "axe", property: "property", propertyValue: "propertyValue", active: "active" }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ParallaxDirective, decorators: [{ type: Directive, args: [{ selector: '[ngx-parallax]', standalone: false }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: BrowserWindowRef }], propDecorators: { speed: [{ type: Input }], axe: [{ type: Input }], property: [{ type: Input }], propertyValue: [{ type: Input }], active: [{ type: Input }] } }); class NgxParallaxModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: NgxParallaxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.7", ngImport: i0, type: NgxParallaxModule, declarations: [ParallaxDirective], exports: [ParallaxDirective] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: NgxParallaxModule }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: NgxParallaxModule, decorators: [{ type: NgModule, args: [{ declarations: [ParallaxDirective], imports: [], exports: [ParallaxDirective] }] }] }); class ParallaxStandaloneDirective { hostElement; renderer; wr; speed = 30; axe = 'y'; property = 'transform'; propertyValue = 'translate3d'; active = true; inViewport = true; observer; element; initialPosition; componentDestroy$ = new Subject(); windowScroll$; windowResize$; constructor(hostElement, renderer, wr) { this.hostElement = hostElement; this.renderer = renderer; this.wr = wr; } ngAfterViewInit() { this.element = this.hostElement.nativeElement; if (this.element && this.wr.nativeWindow && !this.observer) { this.initParallax(); } } initParallax() { this.observer = this.createObserver(0); this.observer.observe(this.element); const parallax$ = of('').pipe(takeUntil(this.componentDestroy$), filter(() => this.active && this.inViewport), map(() => { const coef = this.calculateCoef(); this.renderParallax(coef); return coef; })); this.windowScroll$ = fromEvent(this.wr.nativeWindow, 'scroll').pipe(mergeMap(() => parallax$)); this.windowResize$ = fromEvent(this.wr.nativeWindow, 'resize').pipe(debounceTime(500), mergeMap(() => parallax$)); } startParallax() { this.inViewport = true; if (this.wr.nativeWindow && this.initialPosition === undefined) { this.initialPosition = this.wr.nativeWindow.pageYOffset; this.windowScroll$.subscribe(); this.windowResize$.subscribe(); } } destroyParallax() { this.inViewport = false; } calculateCoef() { return ((this.wr.nativeWindow.pageYOffset - this.initialPosition) * (this.speed / 100)); } renderParallax(coef) { this.renderer.setStyle(this.element, this.property, this.getPropertyValue(coef)); } getPropertyValue(coef) { let result = `${coef}px`; if (this.property === 'transform') { switch (this.propertyValue) { case 'translate3d': result = `translate3d(${this.getAxe(coef)})`; break; case 'scale': result = `scale(${coef})`; break; case 'rotate': result = `rotate(${coef}deg)`; break; } } switch (this.property) { case 'opacity': result = `${coef}`; break; } return result; } getAxe(coef) { let axe = [0, coef, 0]; if (this.axe === 'x') { axe = [coef, 0, 0]; } else if (this.axe === 'z') { axe = [0, 0, coef]; } return `${axe[0]}px, ${axe[1]}px, ${axe[2]}px`; } createObserver(pourcent) { const options = { rootMargin: '0px', threshold: pourcent / 100 }; const isIntersecting = (entry) => entry.isIntersecting || entry.intersectionRatio > 0; return new IntersectionObserver((entries, observer) => { entries.forEach((entry) => { if (isIntersecting(entry)) { this.startParallax(); } else { this.destroyParallax(); } }); }, options); } ngOnDestroy() { this.componentDestroy$.next(false); this.componentDestroy$.complete(); if (this.wr.nativeWindow) { this.observer.disconnect(); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ParallaxStandaloneDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: BrowserWindowRef }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.7", type: ParallaxStandaloneDirective, isStandalone: true, selector: "[ngx-parallax]", inputs: { speed: "speed", axe: "axe", property: "property", propertyValue: "propertyValue", active: "active" }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ParallaxStandaloneDirective, decorators: [{ type: Directive, args: [{ selector: '[ngx-parallax]', standalone: true }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: BrowserWindowRef }], propDecorators: { speed: [{ type: Input }], axe: [{ type: Input }], property: [{ type: Input }], propertyValue: [{ type: Input }], active: [{ type: Input }] } }); /* * Public API Surface of ngx-parallax */ // ngModule /** * Generated bundle index. Do not edit. */ export { NgxParallaxModule, ParallaxDirective, ParallaxStandaloneDirective }; //# sourceMappingURL=yoozly-ngx-parallax.mjs.map