UNPKG

ngx-lottie

Version:

<h1 align="center"> <img src="https://raw.githubusercontent.com/ngx-lottie/ngx-lottie/master/docs/assets/lottie.gif"> </h1>

137 lines 5.82 kB
import { Directive, Input, Output, Inject, PLATFORM_ID, NgZone, } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { Subject, BehaviorSubject, Observable, defer } from 'rxjs'; import { filter, switchMap, takeUntil } from 'rxjs/operators'; import { AnimationLoader } from './animation-loader'; export class BaseDirective { constructor(ngZone, platformId, animationLoader) { this.ngZone = ngZone; this.platformId = platformId; this.animationLoader = animationLoader; this.options = null; this.containerClass = null; this.styles = null; /** * `animationCreated` is dispatched after calling `loadAnimation`. */ this.animationCreated = this.getAnimationItem(); /** * `complete` is dispatched after completing the last frame. */ this.complete = this.awaitAnimationItemAndStartListening('complete'); /** * `loopComplete` is dispatched after completing the frame loop. */ this.loopComplete = this.awaitAnimationItemAndStartListening('loopComplete'); /** * `enterFrame` is dispatched after entering the new frame. */ this.enterFrame = this.awaitAnimationItemAndStartListening('enterFrame'); /** * `segmentStart` is dispatched when the new segment is adjusted. */ this.segmentStart = this.awaitAnimationItemAndStartListening('segmentStart'); /** * Original event name is `config_ready`. `config_ready` is dispatched * after the needed renderer is configured. */ this.configReady = this.awaitAnimationItemAndStartListening('config_ready'); /** * Original event name is `data_ready`. `data_ready` is dispatched * when all parts of the animation have been loaded. */ this.dataReady = this.awaitAnimationItemAndStartListening('data_ready'); /** * Original event name is `DOMLoaded`. `DOMLoaded` is dispatched * when elements have been added to the DOM. */ this.domLoaded = this.awaitAnimationItemAndStartListening('DOMLoaded'); /** * `destroy` will be dispatched when the component gets destroyed, * it's handy for releasing resources. */ this.destroy = this.awaitAnimationItemAndStartListening('destroy'); /** * `error` will be dispatched if the Lottie player could not render * some frame or parse config. */ this.error = this.awaitAnimationItemAndStartListening('error'); this.destroy$ = new Subject(); this.loadAnimation$ = new Subject(); this.animationItem$ = new BehaviorSubject(null); this.setupLoadAnimationListener(); } ngOnDestroy() { this.destroy$.next(); this.destroyAnimation(); } loadAnimation(changes, container) { this.loadAnimation$.next([changes, container]); } getAnimationItem() { return defer(() => this.animationItem$).pipe(filter((animationItem) => animationItem !== null)); } awaitAnimationItemAndStartListening(name) { return this.getAnimationItem().pipe(switchMap(animationItem => // `fromEvent` will try to call `removeEventListener` when `unsubscribe()` is invoked. // The problem is that `ngOnDestroy()` is called before Angular unsubscribes from // `@Output()` properties, thus `animationItem` will be `null` already, also `lottie-web` // removes event listeners when calling `destroy()`. new Observable(observer => { animationItem.addEventListener(name, event => { this.ngZone.runOutsideAngular(() => { observer.next(event); }); }); }))); } setupLoadAnimationListener() { this.loadAnimation$ .pipe(filter(([changes]) => isPlatformBrowser(this.platformId) && changes.options !== undefined), switchMap(([changes, container]) => { this.destroyAnimation(); return this.animationLoader.loadAnimation(this.animationLoader.resolveOptions(changes.options.currentValue, container)); }), takeUntil(this.destroy$)) .subscribe(animationItem => { this.animationItem$.next(animationItem); }); } destroyAnimation() { const animationItem = this.animationItem$.getValue(); // The `ng-lottie` component or the `lottie` directive can be destroyed // before the `animationItem` is set, thus it will fail with // `Cannot read property 'destroy' of null`. // Potentially it can happen if the directive gets destroyed before change // detection is run. if (animationItem === null) { return; } // `destroy()` will remove all events listeners. animationItem.destroy(); this.animationItem$.next(null); } } BaseDirective.decorators = [ { type: Directive, args: [{ selector: '[lottie]' },] } ]; /** @nocollapse */ BaseDirective.ctorParameters = () => [ { type: NgZone }, { type: String, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }, { type: AnimationLoader } ]; BaseDirective.propDecorators = { options: [{ type: Input }], containerClass: [{ type: Input }], styles: [{ type: Input }], animationCreated: [{ type: Output }], complete: [{ type: Output }], loopComplete: [{ type: Output }], enterFrame: [{ type: Output }], segmentStart: [{ type: Output }], configReady: [{ type: Output }], dataReady: [{ type: Output }], domLoaded: [{ type: Output }], destroy: [{ type: Output }], error: [{ type: Output }] }; //# sourceMappingURL=base.directive.js.map