Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> This commit refactors the entire application to replace the 'parties' concept with 'events'. All controllers, models, views, and related files have been updated to reflect this change. The parties table has been replaced with an events table, and all related functionality has been updated accordingly.
71 lines
2.0 KiB
JavaScript
Executable File
71 lines
2.0 KiB
JavaScript
Executable File
import { Controller } from "@hotwired/stimulus"
|
|
|
|
export default class extends Controller {
|
|
static values = {
|
|
target: { type: Number, default: 0 },
|
|
decimal: { type: Boolean, default: false },
|
|
duration: { type: Number, default: 2000 }
|
|
}
|
|
|
|
connect() {
|
|
this.observer = new IntersectionObserver((entries) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
this.animate()
|
|
this.observer.unobserve(this.element)
|
|
}
|
|
})
|
|
}, { threshold: 0.5 })
|
|
|
|
this.observer.observe(this.element)
|
|
}
|
|
|
|
disconnect() {
|
|
if (this.observer) {
|
|
this.observer.disconnect()
|
|
}
|
|
}
|
|
|
|
animate() {
|
|
// Find the target element with data-target-value
|
|
const targetElement = this.element.querySelector('.stat-number');
|
|
if (!targetElement) return;
|
|
|
|
// Get the target value
|
|
this.targetValue = parseInt(targetElement.getAttribute('data-target-value'), 10) || this.targetValue;
|
|
|
|
const startValue = 0;
|
|
const startTime = performance.now();
|
|
|
|
const updateCounter = (currentTime) => {
|
|
const elapsedTime = currentTime - startTime;
|
|
const progress = Math.min(elapsedTime / this.durationValue, 1);
|
|
|
|
// Easing function for smooth animation
|
|
const easeOutQuart = 1 - Math.pow(1 - progress, 4);
|
|
|
|
let currentValue = startValue + (this.targetValue - startValue) * easeOutQuart;
|
|
|
|
if (this.decimalValue && this.targetValue < 10) {
|
|
currentValue = currentValue.toFixed(1);
|
|
} else {
|
|
currentValue = Math.floor(currentValue);
|
|
}
|
|
|
|
// Update only the text content of the target element
|
|
targetElement.textContent = currentValue;
|
|
|
|
if (progress < 1) {
|
|
requestAnimationFrame(updateCounter);
|
|
} else {
|
|
const finalValue = this.decimalValue && this.targetValue < 10
|
|
? this.targetValue.toFixed(1)
|
|
: this.targetValue;
|
|
targetElement.textContent = finalValue;
|
|
}
|
|
}
|
|
|
|
requestAnimationFrame(updateCounter);
|
|
}
|
|
}
|