diff --git a/app/javascript/application.js b/app/javascript/application.js index d933293..758b72d 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -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)) +}) diff --git a/app/javascript/components/counter.js b/app/javascript/components/counter.js new file mode 100644 index 0000000..5452a54 --- /dev/null +++ b/app/javascript/components/counter.js @@ -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)) +}) \ No newline at end of file diff --git a/app/javascript/controllers/counter_controller.js b/app/javascript/controllers/counter_controller.js new file mode 100644 index 0000000..139597f --- /dev/null +++ b/app/javascript/controllers/counter_controller.js @@ -0,0 +1,2 @@ + + diff --git a/app/views/pages/home.html.erb b/app/views/pages/home.html.erb index 27b4f28..f546bbe 100644 --- a/app/views/pages/home.html.erb +++ b/app/views/pages/home.html.erb @@ -3,9 +3,9 @@

- Découvrez la nuit parisienne - - comme jamais + Découvrez les afterworks et soirée + + à Paris

@@ -18,6 +18,101 @@

+ +
+
+
+

+ Des chiffres qui parlent +

+

+ La plateforme préférée des Parisiens pour vivre la nuit +

+
+ +
+ +
+
+
+
+
+ 0 +
+

+ Événements organisés +

+
+
+
+
+ + +
+
+
+
+
+ 0+ +
+

+ Membres actifs +

+
+
+
+
+ + +
+
+
+
+
+ 0/5 +
+

+ Note moyenne des soirées +

+
+
+
+
+
+ + +
+
+
+ 0% +
+

Taux de remplissage

+
+ +
+
+ 0 +
+

Arrondissements

+
+ +
+
+ 0 +
+

Établissements partenaires

+
+ +
+
+ 0% +
+

Satisfaction client

+
+
+
+
+