UNPKG

ng-cw-v12

Version:

Angular UI component library

223 lines (218 loc) 9.64 kB
import * as i0 from '@angular/core'; import { Component, Input, NgModule } from '@angular/core'; import { trigger, state, style, transition, animate } from '@angular/animations'; import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; class NumberCounterComponent { constructor(elementRef) { this.elementRef = elementRef; /** 要显示的数字 */ this._value = 0; /** 每个数字动画持续时间 */ this.ncDuration = 1000; /** 每个数字之间的延迟 */ this.ncDelayMultiple = 0; /** 存在每个数字之间的延迟时,数字方向 */ this.ncDirection = 'left'; /** 每个数字之间的间距 */ this.ncGap = 0; /** 开始前的延迟 */ this.ncDelay = 0; /** 是否在视图可见时才开始动画 */ this._startOnView = false; /** 是否只执行一次动画 */ this._once = false; this.digits = []; this.observer = null; this.timeout = null; } set ncValue(value) { this._value = value; setTimeout(() => { this.start(); }); } get ncValue() { return this._value; } set ncStartOnView(val) { this._startOnView = val !== null && val !== undefined && val !== false && val !== 'false'; } get ncStartOnView() { return this._startOnView; } set ncOnce(val) { this._once = val !== null && val !== undefined && val !== false && val !== 'false'; } get ncOnce() { return this._once; } ngOnInit() { } ngOnDestroy() { this.clear(); } start() { this.clear(); if (!this.ncStartOnView) { this.processValue(); this.timeout = setTimeout(() => { this.startAnimation(); }, this.ncDelay); } else { this.setupIntersectionObserver(); } } clear() { if (this.observer) { this.observer.disconnect(); } if (this.timeout) { clearTimeout(this.timeout); } } setupIntersectionObserver() { this.observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting) { this.processValue(); this.timeout = setTimeout(() => { this.startAnimation(); }, this.ncDelay); if (this.ncOnce) { if (this.observer) { this.observer.disconnect(); } } } else if (!this.ncOnce) { this.resetAnimation(); } }, { threshold: 0.1 }); this.observer.observe(this.elementRef.nativeElement); } processValue() { this.digits = []; const stringValue = this.ncValue.toString(); for (let i = 0; i < stringValue.length; i++) { const digit = parseInt(stringValue[i]); // 对于所有数字,都生成0到9的序列,然后再从0到最终数字 let numbers = [ ...Array.from({ length: 10 }, (_, index) => index), ...Array.from({ length: digit + 1 }, (_, index) => index) ]; let delay = 0; if (this.ncDirection === 'left') { delay = (stringValue.length - 1 - i) * this.ncDelayMultiple; } else { delay = i * this.ncDelayMultiple; } this.digits.push({ numbers: numbers, targetPosition: -(numbers.length - 1), state: 'initial', delay: delay }); } } startAnimation() { this.digits.forEach((digit) => { setTimeout(() => { digit.state = 'final'; }, digit.delay); }); } resetAnimation() { if (this.timeout) { clearTimeout(this.timeout); } this.digits.forEach(digit => { digit.state = 'initial'; }); } } NumberCounterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NumberCounterComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); NumberCounterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: NumberCounterComponent, selector: "nc-number-counter", inputs: { ncValue: "ncValue", ncDuration: "ncDuration", ncDelayMultiple: "ncDelayMultiple", ncDirection: "ncDirection", ncGap: "ncGap", ncDelay: "ncDelay", ncStartOnView: "ncStartOnView", ncOnce: "ncOnce" }, ngImport: i0, template: "<div class=\"number-counter-container\" [ngClass]=\"{'gap-x': ncGap > 0}\" [style.--gap.px]=\"ncGap\">\n <div class=\"digit-wrapper\" *ngFor=\"let digit of digits; let i = index\">\n <div class=\"digits-strip\"\n [@countAnimation]=\"{value: digit.state, params: {duration: ncDuration, delay: digit.delay, finalPosition: digit.targetPosition}}\">\n <div class=\"digit\" *ngFor=\"let num of digit.numbers\">{{num}}</div>\n </div>\n </div>\n</div>", styles: [":host{display:inline-block}.number-counter-container{display:flex;width:-moz-fit-content;width:fit-content}.gap-x>*+*{margin-left:var(--gap)}.digit-wrapper{overflow:hidden;position:relative;height:1em;line-height:1em}.digit-wrapper .digits-strip{width:100%;transform:translateY(0);will-change:transform}\n"], directives: [{ type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], animations: [ trigger('countAnimation', [ state('initial', style({ transform: 'translateY(0)' })), state('final', style({ transform: 'translateY({{finalPosition}}em)' }), { params: { finalPosition: 0 } }), transition('initial => final', [ animate('{{duration}}ms {{delay}}ms cubic-bezier(0.33, 1, 0.68, 1)') ], { params: { duration: 1000, delay: 0 } }) ]) ] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NumberCounterComponent, decorators: [{ type: Component, args: [{ selector: 'nc-number-counter', templateUrl: './number-counter.component.html', styleUrls: ['./number-counter.component.less'], animations: [ trigger('countAnimation', [ state('initial', style({ transform: 'translateY(0)' })), state('final', style({ transform: 'translateY({{finalPosition}}em)' }), { params: { finalPosition: 0 } }), transition('initial => final', [ animate('{{duration}}ms {{delay}}ms cubic-bezier(0.33, 1, 0.68, 1)') ], { params: { duration: 1000, delay: 0 } }) ]) ] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { ncValue: [{ type: Input }], ncDuration: [{ type: Input }], ncDelayMultiple: [{ type: Input }], ncDirection: [{ type: Input }], ncGap: [{ type: Input }], ncDelay: [{ type: Input }], ncStartOnView: [{ type: Input }], ncOnce: [{ type: Input }] } }); class NcNumberCounterModule { } NcNumberCounterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcNumberCounterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); NcNumberCounterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcNumberCounterModule, declarations: [NumberCounterComponent], imports: [CommonModule], exports: [NumberCounterComponent] }); NcNumberCounterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcNumberCounterModule, imports: [[ CommonModule ]] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcNumberCounterModule, decorators: [{ type: NgModule, args: [{ declarations: [ NumberCounterComponent ], imports: [ CommonModule ], exports: [ NumberCounterComponent ] }] }] }); /** * Generated bundle index. Do not edit. */ export { NcNumberCounterModule, NumberCounterComponent }; //# sourceMappingURL=ng-cw-v12-number-counter.js.map