@yoozly/ngx-parallax
Version:
Use parallax effect with Angular 19 compatible universal (standalone and ngModule)
324 lines (316 loc) • 12.3 kB
JavaScript
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