Files
aperonight/app/javascript/controllers/counter_controller.js
Kevin BATAILLE 30f3ecc6ad refactor(events): replace parties concept with events throughout the application
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.
2025-08-28 13:20:51 +02:00

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);
}
}