feat(blackjack): add animated number component and usage
This commit is contained in:
parent
a2f1a40931
commit
4b70a4ac4a
11 changed files with 127 additions and 63 deletions
|
@ -0,0 +1,80 @@
|
|||
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
|
||||
import { CommonModule, CurrencyPipe } from '@angular/common';
|
||||
import { CountUp } from 'countup.js';
|
||||
|
||||
@Component({
|
||||
selector: 'app-animated-number',
|
||||
standalone: true,
|
||||
imports: [CommonModule, CurrencyPipe],
|
||||
template: `
|
||||
<span #numberElement>{{ formattedValue }}</span>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AnimatedNumberComponent implements OnChanges, AfterViewInit {
|
||||
@Input() value = 0;
|
||||
@Input() duration = 1;
|
||||
@Input() ease = 'power1.out';
|
||||
|
||||
@ViewChild('numberElement') numberElement!: ElementRef;
|
||||
|
||||
private countUp: CountUp | null = null;
|
||||
private previousValue = 0;
|
||||
formattedValue = '0,00 €';
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.initializeCountUp();
|
||||
if (this.countUp && this.value !== 0) {
|
||||
this.countUp.start(() => {
|
||||
this.previousValue = this.value;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes['value']) {
|
||||
if (this.countUp) {
|
||||
const startVal = this.previousValue;
|
||||
const endVal = this.value;
|
||||
|
||||
// Update the CountUp instance with new start and end values
|
||||
this.countUp.update(endVal);
|
||||
this.previousValue = endVal;
|
||||
} else {
|
||||
// Format the initial value if CountUp is not yet initialized
|
||||
this.formattedValue = new Intl.NumberFormat('de-DE', {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
}).format(this.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private initializeCountUp(): void {
|
||||
if (this.numberElement) {
|
||||
this.countUp = new CountUp(this.numberElement.nativeElement, this.value, {
|
||||
startVal: this.previousValue,
|
||||
duration: this.duration,
|
||||
easingFn: (t, b, c, d) => {
|
||||
// Custom easing function based on the input ease type
|
||||
if (this.ease === 'power1.out') {
|
||||
return c * (1 - Math.pow(1 - t / d, 1)) + b;
|
||||
}
|
||||
return c * (t / d) + b; // linear fallback
|
||||
},
|
||||
formattingFn: (value) => {
|
||||
const formatted = new Intl.NumberFormat('de-DE', {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
}).format(value);
|
||||
this.formattedValue = formatted;
|
||||
return formatted;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue