From c10812b4c0345ab74d72f8776536266fffc3369e Mon Sep 17 00:00:00 2001 From: Jules Date: Sat, 21 Mar 2026 23:41:56 +0100 Subject: [PATCH] Video/GIF en boucle sur l'ecran d'accueil - Choix d'un media d'accueil dans les parametres Evenement - GIF ou video (MP4/WebM) joue en boucle en fond d'ecran - Import direct depuis le backoffice - Si aucun media, l'animation cercle par defaut est affichee - Le texte (nom evenement, instruction) reste par-dessus Co-Authored-By: Claude Opus 4.6 (1M context) --- data/config.json | 3 ++- frontend/css/style.css | 10 ++++++++++ frontend/index.html | 16 +++++++++++++++- frontend/js/admin.js | 33 ++++++++++++++++++++++++++++++++- frontend/js/app.js | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 3 deletions(-) diff --git a/data/config.json b/data/config.json index 98ff337..b444caf 100644 --- a/data/config.json +++ b/data/config.json @@ -3,7 +3,8 @@ "nom": "Mon Evenement", "logo": null, "couleur_primaire": "#e91e63", - "couleur_secondaire": "#ffffff" + "couleur_secondaire": "#ffffff", + "media_accueil": null }, "fonctionnalites": { "photo_simple": true, diff --git a/frontend/css/style.css b/frontend/css/style.css index c784d20..267fae2 100644 --- a/frontend/css/style.css +++ b/frontend/css/style.css @@ -52,8 +52,18 @@ html, body { } /* === Ecran d'accueil === */ +.accueil-media { + position: absolute; + top: 0; left: 0; + width: 100%; height: 100%; + object-fit: cover; + z-index: 0; +} + .accueil-contenu { text-align: center; + position: relative; + z-index: 1; } .accueil-contenu h1 { diff --git a/frontend/index.html b/frontend/index.html index b8e385b..6c57f4e 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -11,10 +11,13 @@
+ + +

Photobooth

Touchez pour commencer

-
+
@@ -287,6 +290,17 @@
+
+ +
+ + +
+ + +
diff --git a/frontend/js/admin.js b/frontend/js/admin.js index cce30d7..458e1f6 100644 --- a/frontend/js/admin.js +++ b/frontend/js/admin.js @@ -466,11 +466,40 @@ function setupToggleListeners() { // === EVENEMENT === -function chargerEvenementAdmin() { +async function chargerEvenementAdmin() { const event = config.evenement || {}; setValue('admin-nom-event', event.nom); setValue('admin-couleur-primaire', event.couleur_primaire || '#e91e63'); setValue('admin-couleur-secondaire', event.couleur_secondaire || '#ffffff'); + await rafraichirMediaAccueil(); + const select = document.getElementById('admin-media-accueil'); + if (event.media_accueil) select.value = event.media_accueil; +} + +async function rafraichirMediaAccueil() { + const data = await apiGet('/api/animations/custom'); + const select = document.getElementById('admin-media-accueil'); + const valeur = select.value; + select.innerHTML = ''; + for (const nom of data.tous) { + const opt = document.createElement('option'); + opt.value = nom; + opt.textContent = nom; + select.appendChild(opt); + } + if (valeur) select.value = valeur; +} + +async function uploaderMediaAccueil() { + const input = document.getElementById('input-media-accueil'); + if (!input.files.length) return; + + const formData = new FormData(); + formData.append('fichier', input.files[0]); + await fetch('/api/upload/animation', { method: 'POST', body: formData }); + input.value = ''; + await rafraichirMediaAccueil(); + afficherStatut('Media importe', 'succes'); } async function sauvegarderEvenement() { @@ -479,8 +508,10 @@ async function sauvegarderEvenement() { nom: getValue('admin-nom-event'), couleur_primaire: getValue('admin-couleur-primaire'), couleur_secondaire: getValue('admin-couleur-secondaire'), + media_accueil: getValue('admin-media-accueil') || null, }, }); + appliquerConfig(); afficherStatut('Evenement sauvegarde', 'succes'); } diff --git a/frontend/js/app.js b/frontend/js/app.js index cceb20a..3e1809d 100644 --- a/frontend/js/app.js +++ b/frontend/js/app.js @@ -33,8 +33,41 @@ function appliquerConfig() { toggleVisible('btn-imprimer', fonc.impression); toggleVisible('btn-email', fonc.email); toggleVisible('btn-qr', fonc.qr_code); + + // Media d'accueil (video/gif en boucle) + appliquerMediaAccueil(event.media_accueil); } +function appliquerMediaAccueil(media) { + const video = document.getElementById('accueil-video'); + const gif = document.getElementById('accueil-gif'); + const animDefaut = document.getElementById('accueil-animation-defaut'); + + // Reset + video.classList.add('cache'); + gif.classList.add('cache'); + video.pause(); + video.src = ''; + gif.src = ''; + + if (!media) { + // Pas de media, afficher l'animation par defaut + animDefaut.classList.remove('cache'); + return; + } + + animDefaut.classList.add('cache'); + const ext = media.split('.').pop().toLowerCase(); + + if (ext === 'gif') { + gif.src = `/assets/animations/${media}`; + gif.classList.remove('cache'); + } else { + video.src = `/assets/animations/${media}`; + video.classList.remove('cache'); + video.play().catch(() => {}); + } + // --- Navigation --- function allerA(ecran) {