feat: Add metrics on homepage

This commit is contained in:
kbe
2025-08-17 23:39:24 +02:00
parent 17e6711299
commit ba3f36a5e8
5 changed files with 200 additions and 3 deletions

View File

@@ -1,3 +1,16 @@
// Entry point for the build script in your package.json
import "@hotwired/turbo-rails"
import "./controllers"
import Counter from "./components/counter"
// Initialize counters when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
const counters = document.querySelectorAll('.counter')
counters.forEach(counter => new Counter(counter))
})
// Re-initialize counters on Turbo page loads
document.addEventListener('turbo:load', () => {
const counters = document.querySelectorAll('.counter')
counters.forEach(counter => new Counter(counter))
})

View File

@@ -0,0 +1,61 @@
export default class Counter {
constructor(element) {
this.element = element
this.target = parseFloat(element.dataset.target)
this.decimal = element.dataset.decimal === 'true'
this.duration = 2000
this.startTime = null
this.init()
}
init() {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.animate()
observer.unobserve(this.element)
}
})
}, { threshold: 0.5 })
observer.observe(this.element)
}
animate() {
const startValue = 0
const startTime = performance.now()
const updateCounter = (currentTime) => {
const elapsedTime = currentTime - startTime
const progress = Math.min(elapsedTime / this.duration, 1)
// Easing function for smooth animation
const easeOutQuart = 1 - Math.pow(1 - progress, 4)
let currentValue = startValue + (this.target - startValue) * easeOutQuart
if (this.decimal && this.target < 10) {
currentValue = currentValue.toFixed(1)
} else {
currentValue = Math.floor(currentValue)
}
this.element.textContent = currentValue
if (progress < 1) {
requestAnimationFrame(updateCounter)
} else {
this.element.textContent = this.decimal && this.target < 10 ? this.target.toFixed(1) : this.target
}
}
requestAnimationFrame(updateCounter)
}
}
// Initialize all counters
document.addEventListener('DOMContentLoaded', () => {
const counters = document.querySelectorAll('.counter')
counters.forEach(counter => new Counter(counter))
})

View File

@@ -0,0 +1,2 @@