import { Controller } from "@hotwired/stimulus"; export default class extends Controller { static targets = [ "loaderWrapper", "loaderProgressBar", "list", "imagesWrapper", ]; connect() { if (!this.hasListTarget || !this.hasImagesWrapperTarget) { return; } const images = Array.from(this.listTarget.querySelectorAll("img")); // 1️⃣ avant chargement → tout cacher this.loaderWrapperTarget.classList.add("hidden"); this.imagesWrapperTarget.style.opacity = 0; if (images.length > 0) { this.trackImages(images); } } trackImages(images) { let loadedCount = 0; // 2️⃣ début du chargement → afficher le loader this.loaderWrapperTarget.classList.remove("hidden"); this.loaderProgressBarTarget.style.width = "0%"; images.forEach((img) => { if (img.complete) { loadedCount++; this.updateProgress(loadedCount, images.length); } else { img.addEventListener("load", () => { loadedCount++; this.updateProgress(loadedCount, images.length); }); img.addEventListener("error", () => { loadedCount++; this.updateProgress(loadedCount, images.length); }); } }); } updateProgress(loadedCount, total) { const progress = (loadedCount / total) * 100; this.loaderProgressBarTarget.style.width = `${progress}%`; if (loadedCount === total) { // 3️⃣ chargement terminé → masquer le loader + afficher les images setTimeout(() => { this.loaderWrapperTarget.classList.add("hidden"); this.imagesWrapperTarget.style.transition = "opacity .3s ease"; this.imagesWrapperTarget.style.opacity = 1; }, 200); } } }