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
JavaScript
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