ngx-skltn
Version:
Skeleton loader for Angular
344 lines (329 loc) • 16.3 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common'), require('@angular/platform-browser'), require('rxjs'), require('rxjs/operators')) :
typeof define === 'function' && define.amd ? define('ngx-skltn', ['exports', '@angular/core', '@angular/common', '@angular/platform-browser', 'rxjs', 'rxjs/operators'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['ngx-skltn'] = {}, global.ng.core, global.ng.common, global.ng.platformBrowser, global.rxjs, global.rxjs.operators));
}(this, (function (exports, i0, common, platformBrowser, rxjs, operators) { 'use strict';
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () {
return e[k];
}
});
}
});
}
n['default'] = e;
return Object.freeze(n);
}
var i0__namespace = /*#__PURE__*/_interopNamespace(i0);
var SKLTN_CONFIG_TOKEN = new i0.InjectionToken('SkltnConfig');
var SkltnService = /** @class */ (function () {
function SkltnService(config) {
this.ids = [];
this.defaultConfig = {
rectRadius: 4,
bgFill: '#ddd',
flareFill: 'rgba(255, 255, 255, 0.6)',
flareWidth: '150px',
duration: 1200,
delay: 0,
timing: 'ease-in-out',
};
this.config = Object.assign({}, this.defaultConfig, config);
}
return SkltnService;
}());
SkltnService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function SkltnService_Factory() { return new SkltnService(i0__namespace.ɵɵinject(SKLTN_CONFIG_TOKEN)); }, token: SkltnService, providedIn: "root" });
SkltnService.decorators = [
{ type: i0.Injectable, args: [{
providedIn: 'root'
},] }
];
SkltnService.ctorParameters = function () { return [
{ type: undefined, decorators: [{ type: i0.Inject, args: [SKLTN_CONFIG_TOKEN,] }] }
]; };
function generateId() {
return Math.random().toString(32).substr(2, 4);
}
var BonesList = /** @class */ (function () {
function BonesList() {
this.changes = new rxjs.BehaviorSubject([]);
this.map = new Map();
}
BonesList.prototype.add = function (bone) {
var id = generateId();
this.map.set(id, bone);
this.emit();
return id;
};
BonesList.prototype.remove = function (id) {
this.map.delete(id);
this.emit();
};
BonesList.prototype.emit = function () {
var list = this.getList();
this.changes.next(list);
};
BonesList.prototype.getList = function () {
var values = this.map.values();
return Array.from(values);
};
return BonesList;
}());
BonesList.decorators = [
{ type: i0.Injectable }
];
BonesList.ctorParameters = function () { return []; };
var SkltnComponent = /** @class */ (function () {
function SkltnComponent(skltnService, element, sanitizer, cd, zone, bonesList) {
this.skltnService = skltnService;
this.element = element;
this.sanitizer = sanitizer;
this.cd = cd;
this.zone = zone;
this.bonesList = bonesList;
this.showSkltn = true;
this.checkInterval = 100;
this.updStream$ = new rxjs.Subject();
this.checkStream$ = new rxjs.Subject();
this.unsubscribe$ = new rxjs.Subject();
this.defaultConfig = {
rectRadius: 4,
bgFill: '#ddd',
flareFill: 'rgba(255, 255, 255, 0.6)',
flareWidth: '150px',
duration: 1200,
delay: 0,
timing: 'ease-in-out',
};
var conf = this.skltnService.config;
this.rectRadius = conf.rectRadius;
this.bgFill = conf.bgFill;
this.flareFill = conf.flareFill;
this.flareWidth = conf.flareWidth;
this.duration = conf.duration;
this.delay = conf.delay;
this.timing = conf.timing;
this.sufix = this.getSufixWithID();
this.gradientId = 'gradient-' + this.sufix;
this.maskId = 'mask-' + this.sufix;
}
SkltnComponent.prototype.onResize = function (event) {
this.updStream$.next();
};
SkltnComponent.prototype.ngOnInit = function () {
var _this = this;
this.animationCss = this.sanitizer.bypassSecurityTrustHtml("\n <style>\n @keyframes skltnFlareAnimation {\n 0% { x: calc(0% - " + this.flareWidth + "); }\n 100% { x: 100%; }\n }\n .skltn-flare {\n animation-name: skltnFlareAnimation;\n animation-duration: " + this.duration + "ms;\n animation-timing-function: " + this.timing + ";\n animation-iteration-count: infinite;\n animation-delay: " + this.delay + "ms;\n }\n </style>");
// Bones Updates
this.bonesList.changes.pipe(operators.debounceTime(50), operators.tap(function (list) {
_this.bones = list;
_this.calcShapes();
_this.cd.detectChanges();
}), operators.filter(function (list, index) { return index === 0; }), operators.tap(function () {
_this.checkStream$.next();
}), operators.takeUntil(this.unsubscribe$)).subscribe();
// Update
this.updStream$.pipe(operators.throttleTime(50), operators.takeUntil(this.unsubscribe$)).subscribe(function () { return _this.calcShapes(); });
// Update href (Safari Bug, SVG Ref Path)
this.href = window.location.href;
this.zone.runOutsideAngular(function () {
_this.checkStream$.pipe(operators.tap(function () {
// Check if href changed
if (_this.href !== window.location.href) {
_this.href = window.location.href;
_this.cd.detectChanges();
}
// Check if root element resized
var el = _this.element.nativeElement;
var _b = el.getBoundingClientRect(), width = _b.width, height = _b.height;
if (_this.parentClientRect.width !== width || _this.parentClientRect.height !== height) {
_this.updStream$.next();
_this.cd.detectChanges();
}
setTimeout(function () {
_this.checkStream$.next();
}, _this.checkInterval);
}), operators.takeUntil(_this.unsubscribe$)).subscribe();
});
};
SkltnComponent.prototype.ngAfterViewInit = function () {
};
SkltnComponent.prototype.ngOnDestroy = function () {
this.unsubscribe$.next();
this.unsubscribe$.complete();
};
SkltnComponent.prototype.getSufixWithID = function () {
return generateId() + '-skltn';
};
SkltnComponent.prototype.calcShapes = function () {
var _this = this;
var _a;
// Root SVG Element
var el = this.element.nativeElement;
this.parentClientRect = el.getBoundingClientRect();
this.viewBox = "0 0 " + this.parentClientRect.width + " " + this.parentClientRect.height;
// SVG Shapes
if (!((_a = this.bones) === null || _a === void 0 ? void 0 : _a.length)) {
this.shapes = null;
return;
}
this.shapes = this.bones.map(function (bone) {
var boneEl = bone.element.nativeElement;
var clientRect = boneEl.getBoundingClientRect();
var radius = bone.rectRadius || _this.rectRadius;
if (bone.type === 'circle') {
return {
type: 'circle',
cx: clientRect.x - _this.parentClientRect.x + clientRect.width / 2,
cy: clientRect.y - _this.parentClientRect.y + clientRect.height / 2,
rx: clientRect.width / 2,
ry: clientRect.height / 2,
};
}
if (bone.type === 'path') {
var x = clientRect.x - _this.parentClientRect.x;
var y = clientRect.y - _this.parentClientRect.y;
var transform = "translate(" + x + ", " + y + ")";
if (bone.pathWidth && bone.pathHeight) {
var xScale = (clientRect.width / bone.pathWidth).toFixed(2);
var yScale = (clientRect.height / bone.pathHeight).toFixed(2);
transform += " scale(" + xScale + ", " + yScale + ")";
}
return {
type: 'path',
width: clientRect.width,
height: clientRect.height,
transform: transform,
template: bone.template,
};
}
return {
type: 'rect',
x: clientRect.x - _this.parentClientRect.x,
y: clientRect.y - _this.parentClientRect.y,
width: clientRect.width,
height: clientRect.height,
rx: radius,
ry: radius,
};
});
};
return SkltnComponent;
}());
SkltnComponent.decorators = [
{ type: i0.Component, args: [{
selector: 'skltn-root',
template: "<div [innerHTML]=\"animationCss\"></div>\n\n<svg class=\"svg-root\" x=\"0px\" y=\"0px\" [attr.viewBox]=\"viewBox\" *ngIf=\"shapes?.length && showSkltn\">\n\n <!-- Gradient -->\n <linearGradient [attr.id]=\"gradientId\">\n <stop class=\"stop stop--1\" [attr.stop-color]=\"flareFill\" stop-opacity=\"0\" offset=\"0\"></stop>\n <stop class=\"stop stop--2\" [attr.stop-color]=\"flareFill\" stop-opacity=\"1\" offset=\"50%\"></stop>\n <stop class=\"stop stop--3\" [attr.stop-color]=\"flareFill\" stop-opacity=\"0\" offset=\"100%\"></stop>\n </linearGradient>\n\n <defs>\n <!-- Mask -->\n <mask [attr.id]=\"maskId\">\n <!-- Shapes -->\n <ng-container *ngFor=\"let shape of shapes\">\n <!-- Rect Type -->\n <rect *ngIf=\"shape.type === 'rect'\" [attr.x]=\"shape.x\" [attr.y]=\"shape.y\" [attr.rx]=\"shape.rx\"\n [attr.ry]=\"shape.ry\" [attr.width]=\"shape.width\" [attr.height]=\"shape.height\" fill=\"#FFFFFF\" />\n <!-- Circle Type -->\n <ellipse *ngIf=\"shape.type === 'circle'\" [attr.cx]=\"shape.cx\" [attr.cy]=\"shape.cy\" [attr.rx]=\"shape.rx\" [attr.ry]=\"shape.ry\" fill=\"#FFFFFF\"></ellipse>\n <!-- Path Type -->\n <ng-container *ngIf=\"shape.type === 'path'\">\n <g fill=\"#FFFFFF\" [attr.transform]=\"shape.transform\">\n <ng-container *ngTemplateOutlet=\"shape.template\"></ng-container>\n </g>\n </ng-container>\n </ng-container>\n </mask>\n </defs>\n\n <g [attr.mask]=\"'url(' + href + '#' + maskId + ')'\">\n <!-- Background Rectangle -->\n <rect class=\"bg-fill\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" [attr.fill]=\"bgFill\"></rect>\n\n <!-- Flare -->\n <rect class=\"skltn-flare\" [attr.x]=\"'-' + flareWidth\" y=\"0\" [attr.width]=\"flareWidth\" height=\"100%\" [attr.fill]=\"'url(' + href + '#' + gradientId + ')'\"></rect>\n </g>\n\n</svg>\n\n<ng-content></ng-content>\n",
providers: [{
provide: BonesList,
useClass: BonesList,
}],
styles: [":host{display:block;position:relative}.svg-root{display:block;position:absolute;top:0;bottom:0;left:0;right:0;z-index:1}"]
},] }
];
SkltnComponent.ctorParameters = function () { return [
{ type: SkltnService },
{ type: i0.ElementRef },
{ type: platformBrowser.DomSanitizer },
{ type: i0.ChangeDetectorRef },
{ type: i0.NgZone },
{ type: BonesList }
]; };
SkltnComponent.propDecorators = {
rectRadius: [{ type: i0.Input }],
bgFill: [{ type: i0.Input }],
flareFill: [{ type: i0.Input }],
flareWidth: [{ type: i0.Input }],
duration: [{ type: i0.Input }],
delay: [{ type: i0.Input }],
timing: [{ type: i0.Input }],
showSkltn: [{ type: i0.Input }],
checkInterval: [{ type: i0.Input }],
onResize: [{ type: i0.HostListener, args: ['window:resize', ['$event'],] }]
};
var SkltnBoneDirective = /** @class */ (function () {
function SkltnBoneDirective(element, bonesList) {
this.element = element;
this.bonesList = bonesList;
}
SkltnBoneDirective.prototype.ngOnInit = function () {
this.id = this.bonesList.add(this);
};
SkltnBoneDirective.prototype.ngOnDestroy = function () {
this.bonesList.remove(this.id);
};
return SkltnBoneDirective;
}());
SkltnBoneDirective.decorators = [
{ type: i0.Directive, args: [{
selector: '[skltn-bone]',
},] }
];
SkltnBoneDirective.ctorParameters = function () { return [
{ type: i0.ElementRef },
{ type: BonesList }
]; };
SkltnBoneDirective.propDecorators = {
type: [{ type: i0.Input }],
rectRadius: [{ type: i0.Input }],
pathWidth: [{ type: i0.Input }],
pathHeight: [{ type: i0.Input }],
template: [{ type: i0.ContentChild, args: ['boneTemp', { static: true },] }]
};
var NgxSkltnModule = /** @class */ (function () {
function NgxSkltnModule() {
}
NgxSkltnModule.forRoot = function (config) {
if (config === void 0) { config = {}; }
return {
ngModule: NgxSkltnModule,
providers: [{
provide: SKLTN_CONFIG_TOKEN,
useValue: config,
},
{
provide: SkltnService,
useClass: SkltnService,
deps: [SKLTN_CONFIG_TOKEN],
}]
};
};
return NgxSkltnModule;
}());
NgxSkltnModule.decorators = [
{ type: i0.NgModule, args: [{
declarations: [
SkltnComponent,
SkltnBoneDirective,
],
imports: [
common.CommonModule,
],
exports: [
SkltnComponent,
SkltnBoneDirective,
]
},] }
];
/*
* Public API Surface of ngx-skltn
*/
/**
* Generated bundle index. Do not edit.
*/
exports.NgxSkltnModule = NgxSkltnModule;
exports.SKLTN_CONFIG_TOKEN = SKLTN_CONFIG_TOKEN;
exports.SkltnBoneDirective = SkltnBoneDirective;
exports.SkltnComponent = SkltnComponent;
exports.SkltnService = SkltnService;
exports.ɵa = BonesList;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=ngx-skltn.umd.js.map