Surprise : precharger image + animation fade in/out + attente chargement

Evite le freeze percu : image prechargee au boot, fade 200ms,
attente img.onload si pas encore prete, re-precharge apres affichage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-17 19:09:53 +02:00
parent 6b2928c9af
commit 05f78f731d
3 changed files with 38 additions and 4 deletions

View File

@@ -1145,8 +1145,8 @@
</style>
<script src="/js/websocket.js?v=16"></script>
<script src="/js/app.js?v=24"></script>
<script src="/js/camera.js?v=20"></script>
<script src="/js/app.js?v=25"></script>
<script src="/js/camera.js?v=21"></script>
<script src="/js/effects.js?v=4"></script>
<script src="/js/gallery.js?v=5"></script>
<script src="/js/share.js?v=9"></script>

View File

@@ -64,6 +64,9 @@ function appliquerConfig() {
// Media d'accueil (video/gif en boucle)
appliquerMediaAccueil(event.media_accueil);
// Precharger image surprise
if (typeof prechargerSurprise === 'function') prechargerSurprise();
}
function appliquerMediaAccueil(media) {

View File

@@ -11,23 +11,54 @@ const EMOJI_CAR = { 3: '🤪', 2: '😱', 1: '🔥' };
// --- Surprise avant capture ---
let _surprisePreloaded = null;
function prechargerSurprise() {
const surprise = (config || {}).surprise;
if (!surprise || !surprise.actif || !surprise.fichier) return;
if (surprise.type === 'video') return;
const img = new Image();
img.src = '/api/surprise/media?t=' + Date.now();
_surprisePreloaded = img;
}
async function afficherSurprise() {
const surprise = (config || {}).surprise;
if (!surprise || !surprise.actif || !surprise.fichier) return;
const delai = surprise.delai_ms || 1000;
const delai = surprise.delai_ms || 1500;
const overlay = document.getElementById('surprise-overlay');
if (!overlay) return;
if (surprise.type === 'video') {
overlay.innerHTML = '<video src="/api/surprise/media" autoplay muted playsinline style="max-width:100%;max-height:100%;object-fit:contain"></video>';
} else {
if (_surprisePreloaded && _surprisePreloaded.complete) {
_surprisePreloaded.style.cssText = 'max-width:100%;max-height:100%;object-fit:contain';
overlay.innerHTML = '';
overlay.appendChild(_surprisePreloaded);
} else {
overlay.innerHTML = '<img src="/api/surprise/media" style="max-width:100%;max-height:100%;object-fit:contain">';
const img = overlay.querySelector('img');
if (img && !img.complete) {
await new Promise(r => { img.onload = r; img.onerror = r; setTimeout(r, 500); });
}
}
}
overlay.style.opacity = '0';
overlay.classList.remove('cache');
overlay.style.transition = 'opacity 0.2s';
overlay.style.opacity = '1';
await new Promise(r => setTimeout(r, delai));
overlay.style.opacity = '0';
await new Promise(r => setTimeout(r, 200));
overlay.classList.add('cache');
overlay.style.transition = '';
overlay.style.opacity = '';
prechargerSurprise();
}
// --- Preview live ---