UNPKG

@yoozly/ngx-parallax

Version:

Use parallax effect with Angular 16-17 compatible universal (standalone and ngModule)

138 lines 16.6 kB
import { Directive, Input } from '@angular/core'; import { fromEvent, of, Subject } from 'rxjs'; import { takeUntil, filter, map, debounceTime, mergeMap } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "./services/windowref.service"; export 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: "17.2.3", ngImport: i0, type: ParallaxStandaloneDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.BrowserWindowRef }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.3", 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: "17.2.3", ngImport: i0, type: ParallaxStandaloneDirective, decorators: [{ type: Directive, args: [{ selector: '[ngx-parallax]', standalone: true }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.BrowserWindowRef }], propDecorators: { speed: [{ type: Input }], axe: [{ type: Input }], property: [{ type: Input }], propertyValue: [{ type: Input }], active: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXBhcmFsbGF4LXN0YW5kYWxvbmUuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXBhcmFsbGF4L3NyYy9saWIvbmd4LXBhcmFsbGF4LXN0YW5kYWxvbmUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUtOLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFRaEYsTUFBTSxPQUFPLDJCQUEyQjtJQWdCNUI7SUFDQTtJQUNBO0lBakJELEtBQUssR0FBRyxFQUFFLENBQUM7SUFDWCxHQUFHLEdBQUcsR0FBRyxDQUFDO0lBQ1YsUUFBUSxHQUFHLFdBQVcsQ0FBQztJQUN2QixhQUFhLEdBQUcsYUFBYSxDQUFDO0lBQzlCLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFFZixVQUFVLEdBQUcsSUFBSSxDQUFDO0lBQ2xCLFFBQVEsQ0FBdUI7SUFDL0IsT0FBTyxDQUFjO0lBQ3JCLGVBQWUsQ0FBUztJQUN4QixpQkFBaUIsR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO0lBQzNDLGFBQWEsQ0FBcUI7SUFDbEMsYUFBYSxDQUFxQjtJQUUxQyxZQUNVLFdBQXVCLEVBQ3ZCLFFBQW1CLEVBQ25CLEVBQW9CO1FBRnBCLGdCQUFXLEdBQVgsV0FBVyxDQUFZO1FBQ3ZCLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsT0FBRSxHQUFGLEVBQUUsQ0FBa0I7SUFDM0IsQ0FBQztJQUVKLGVBQWU7UUFDYixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDO1FB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TyxJQUFJLG9CQUFvQixDQUFDLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFO1lBQ3BELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDeEIsSUFBSSxjQUFjLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDMUIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN2QixDQUFDO3FCQUFNLENBQUM7b0JBQ04sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN6QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDZCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2xDLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzdCLENBQUM7SUFDSCxDQUFDO3VHQWxKVSwyQkFBMkI7MkZBQTNCLDJCQUEyQjs7MkZBQTNCLDJCQUEyQjtrQkFKdkMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsZ0JBQWdCO29CQUMxQixVQUFVLEVBQUUsSUFBSTtpQkFDakI7c0lBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLEdBQUc7c0JBQVgsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRGlyZWN0aXZlLFxuICBJbnB1dCxcbiAgRWxlbWVudFJlZixcbiAgUmVuZGVyZXIyLFxuICBPbkRlc3Ryb3ksXG4gIEFmdGVyVmlld0luaXRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBmcm9tRXZlbnQsIE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwsIGZpbHRlciwgbWFwLCBkZWJvdW5jZVRpbWUsIG1lcmdlTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBCcm93c2VyV2luZG93UmVmIH0gZnJvbSAnLi9zZXJ2aWNlcy93aW5kb3dyZWYuc2VydmljZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tuZ3gtcGFyYWxsYXhdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZVxufSlcbmV4cG9ydCBjbGFzcyBQYXJhbGxheFN0YW5kYWxvbmVEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuICBASW5wdXQoKSBzcGVlZCA9IDMwO1xuICBASW5wdXQoKSBheGUgPSAneSc7XG4gIEBJbnB1dCgpIHByb3BlcnR5ID0gJ3RyYW5zZm9ybSc7XG4gIEBJbnB1dCgpIHByb3BlcnR5VmFsdWUgPSAndHJhbnNsYXRlM2QnO1xuICBASW5wdXQoKSBhY3RpdmUgPSB0cnVlO1xuXG4gIHByaXZhdGUgaW5WaWV3cG9ydCA9IHRydWU7XG4gIHByaXZhdGUgb2JzZXJ2ZXI6IEludGVyc2VjdGlvbk9ic2VydmVyO1xuICBwcml2YXRlIGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICBwcml2YXRlIGluaXRpYWxQb3NpdGlvbjogbnVtYmVyO1xuICBwcml2YXRlIGNvbXBvbmVudERlc3Ryb3kkID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgcHJpdmF0ZSB3aW5kb3dTY3JvbGwkOiBPYnNlcnZhYmxlPG51bWJlcj47XG4gIHByaXZhdGUgd2luZG93UmVzaXplJDogT2JzZXJ2YWJsZTxudW1iZXI+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgaG9zdEVsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgd3I6IEJyb3dzZXJXaW5kb3dSZWZcbiAgKSB7fVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBpZiAodGhpcy5lbGVtZW50ICYmIHRoaXMud3IubmF0aXZlV2luZG93ICYmICF0aGlzLm9ic2VydmVyKSB7XG4gICAgICB0aGlzLmluaXRQYXJhbGxheCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdFBhcmFsbGF4KCk6IHZvaWQge1xuICAgIHRoaXMub2JzZXJ2ZXIgPSB0aGlzLmNyZWF0ZU9ic2VydmVyKDApO1xuICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQpO1xuXG4gICAgY29uc3QgcGFyYWxsYXgkID0gb2YoJycpLnBpcGUoXG4gICAgICB0YWtlVW50aWwodGhpcy5jb21wb25lbnREZXN0cm95JCksXG4gICAgICBmaWx0ZXIoKCkgPT4gdGhpcy5hY3RpdmUgJiYgdGhpcy5pblZpZXdwb3J0KSxcbiAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvZWYgPSB0aGlzLmNhbGN1bGF0ZUNvZWYoKTtcbiAgICAgICAgdGhpcy5yZW5kZXJQYXJhbGxheChjb2VmKTtcbiAgICAgICAgcmV0dXJuIGNvZWY7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLndpbmRvd1Njcm9sbCQgPSBmcm9tRXZlbnQodGhpcy53ci5uYXRpdmVXaW5kb3csICdzY3JvbGwnKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKCkgPT4gcGFyYWxsYXgkKVxuICAgICk7XG5cbiAgICB0aGlzLndpbmRvd1Jlc2l6ZSQgPSBmcm9tRXZlbnQodGhpcy53ci5uYXRpdmVXaW5kb3csICdyZXNpemUnKS5waXBlKFxuICAgICAgZGVib3VuY2VUaW1lKDUwMCksXG4gICAgICBtZXJnZU1hcCgoKSA9PiBwYXJhbGxheCQpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRQYXJhbGxheCgpOiB2b2lkIHtcbiAgICB0aGlzLmluVmlld3BvcnQgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMud3IubmF0aXZlV2luZG93ICYmIHRoaXMuaW5pdGlhbFBvc2l0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuaW5pdGlhbFBvc2l0aW9uID0gdGhpcy53ci5uYXRpdmVXaW5kb3cucGFnZVlPZmZzZXQ7XG4gICAgICB0aGlzLndpbmRvd1Njcm9sbCQuc3Vic2NyaWJlKCk7XG4gICAgICB0aGlzLndpbmRvd1Jlc2l6ZSQuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZXN0cm95UGFyYWxsYXgoKTogdm9pZCB7XG4gICAgdGhpcy5pblZpZXdwb3J0ID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIGNhbGN1bGF0ZUNvZWYoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKFxuICAgICAgKHRoaXMud3IubmF0aXZlV2luZG93LnBhZ2VZT2Zmc2V0IC0gdGhpcy5pbml0aWFsUG9zaXRpb24pICpcbiAgICAgICh0aGlzLnNwZWVkIC8gMTAwKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlclBhcmFsbGF4KGNvZWY6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICB0aGlzLmVsZW1lbnQsXG4gICAgICB0aGlzLnByb3BlcnR5LFxuICAgICAgdGhpcy5nZXRQcm9wZXJ0eVZhbHVlKGNvZWYpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UHJvcGVydHlWYWx1ZShjb2VmOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGxldCByZXN1bHQgPSBgJHtjb2VmfXB4YDtcblxuICAgIGlmICh0aGlzLnByb3BlcnR5ID09PSAndHJhbnNmb3JtJykge1xuICAgICAgc3dpdGNoICh0aGlzLnByb3BlcnR5VmFsdWUpIHtcbiAgICAgICAgY2FzZSAndHJhbnNsYXRlM2QnOlxuICAgICAgICAgIHJlc3VsdCA9IGB0cmFuc2xhdGUzZCgke3RoaXMuZ2V0QXhlKGNvZWYpfSlgO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdzY2FsZSc6XG4gICAgICAgICAgcmVzdWx0ID0gYHNjYWxlKCR7Y29lZn0pYDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAncm90YXRlJzpcbiAgICAgICAgICByZXN1bHQgPSBgcm90YXRlKCR7Y29lZn1kZWcpYDtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRoaXMucHJvcGVydHkpIHtcbiAgICAgIGNhc2UgJ29wYWNpdHknOlxuICAgICAgICByZXN1bHQgPSBgJHtjb2VmfWA7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIGdldEF4ZShjb2VmOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGxldCBheGUgPSBbMCwgY29lZiwgMF07XG5cbiAgICBpZiAodGhpcy5heGUgPT09ICd4Jykge1xuICAgICAgYXhlID0gW2NvZWYsIDAsIDBdO1xuICAgIH0gZWxzZSBpZiAodGhpcy5heGUgPT09ICd6Jykge1xuICAgICAgYXhlID0gWzAsIDAsIGNvZWZdO1xuICAgIH1cblxuICAgIHJldHVybiBgJHtheGVbMF19cHgsICR7YXhlWzFdfXB4LCAke2F4ZVsyXX1weGA7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU9ic2VydmVyKHBvdXJjZW50OiBudW1iZXIpIHtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgcm9vdE1hcmdpbjogJzBweCcsXG4gICAgICB0aHJlc2hvbGQ6IHBvdXJjZW50IC8gMTAwXG4gICAgfTtcblxuICAgIGNvbnN0IGlzSW50ZXJzZWN0aW5nID0gKGVudHJ5OiBJbnRlcnNlY3Rpb25PYnNlcnZlckVudHJ5KSA9PlxuICAgICAgZW50cnkuaXNJbnRlcnNlY3RpbmcgfHwgZW50cnkuaW50ZXJzZWN0aW9uUmF0aW8gPiAwO1xuXG4gICAgcmV0dXJuIG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcigoZW50cmllcywgb2JzZXJ2ZXIpID0+IHtcbiAgICAgIGVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgICAgaWYgKGlzSW50ZXJzZWN0aW5nKGVudHJ5KSkge1xuICAgICAgICAgIHRoaXMuc3RhcnRQYXJhbGxheCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuZGVzdHJveVBhcmFsbGF4KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0sIG9wdGlvbnMpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5jb21wb25lbnREZXN0cm95JC5uZXh0KGZhbHNlKTtcbiAgICB0aGlzLmNvbXBvbmVudERlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgaWYgKHRoaXMud3IubmF0aXZlV2luZG93KSB7XG4gICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==