ng-cw-v12
Version:
Angular UI component library
223 lines (218 loc) • 9.64 kB
JavaScript
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