#layer-30s { display: none; }
#layer-30s.is-visible { display: block; }
document.addEventListener(‘DOMContentLoaded’, function () {
setTimeout(function () {
var el = document.getElementById(‘layer-30s’);
if (el) el.classList.add(‘is-visible’);
}, 92100);
});
/* Hauteur via padding + base */
/*
#LayerVideo {
padding-top: 320px;
padding-bottom: 320px;
position: relative;
}
*/
#LayerVideo {
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Caché mais conserve la hauteur (pas de display:none) */
#LayerVideo.is-prehidden {
display: block !important;
visibility: hidden;
opacity: 0;
/*pointer-events: none;*/
}
/* Affiché */
#LayerVideo.is-visible {
visibility: visible;
opacity: 1;
/*pointer-events: auto;*/
transition: opacity .25s ease;
}
/* États lecture (contrôle du bouton) */
#LayerVideo.is-playing .layervideo-btn { opacity: 0; visibility: hidden; }
#LayerVideo.is-paused .layervideo-btn,
#LayerVideo.is-ended .layervideo-btn { opacity: 1; visibility: visible; }
(function () {
// Timecode d’arrêt en secondes (1:28.50)
var STOP_AT = 92.1;
function findBackgroundVideo(root) {
if (!root) return null;
var v = root.querySelector(‘video’);
if (v) return v;
v = root.querySelector(‘.fusion-background-video video, .video-bg video, .fusion-video-bg’);
if (v && v.tagName && v.tagName.toLowerCase() === ‘video’) return v;
return null;
}
function initLayerVideo() {
var container = document.getElementById(‘LayerVideo’);
if (!container) return;
// S’assurer que le conteneur réserve sa hauteur avant affichage
if (!container.classList.contains(‘is-prehidden’) && !container.classList.contains(‘is-visible’)) {
container.classList.add(‘is-prehidden’);
}
var video = findBackgroundVideo(container);
var btn = container.querySelector(‘#LayerVideoPlay’);
// Si la vidéo n’est pas encore dans le DOM (lazy Avada), réessaie
if (!video) {
setTimeout(initLayerVideo, 400);
return;
}
// Sécurise les attributs pour lecture fiable (notamment mobile)
video.setAttribute(‘playsinline’, ”);
video.setAttribute(‘webkit-playsinline’, ”);
if (!video.hasAttribute(‘muted’)) {
video.muted = true;
video.setAttribute(‘muted’, ”);
}
// Empêche un éventuel loop d’Avada au-delà du timecode
try { video.loop = false; } catch(e) {}
// Gestion des états d’UI
function setState(state) {
container.classList.remove(‘is-playing’,’is-paused’,’is-ended’);
container.classList.add(state);
}
function showLayer() {
container.classList.remove(‘is-prehidden’);
container.classList.add(‘is-visible’);
}
// Coupe à STOP_AT proprement
function clampAtStop() {
// marge pour compenser la granularité ‘timeupdate’ (Safari notamment)
var epsilon = 0.05;
if (video.currentTime >= STOP_AT – epsilon) {
// Fige exactement au frame cible
try { video.currentTime = STOP_AT; } catch(e) {}
// Stoppe et marque comme terminé
try { video.pause(); } catch(e) {}
setState(‘is-ended’);
}
}
// Événements vidéo
video.addEventListener(‘timeupdate’, clampAtStop);
// Sécurité supplémentaire si ‘timeupdate’ est peu fréquent
var clampTimer = setInterval(clampAtStop, 100);
video.addEventListener(‘playing’, function(){ setState(‘is-playing’); });
video.addEventListener(‘pause’, function(){
// Si on a atteint le timecode d’arrêt, considérer comme terminé
if (video.currentTime >= STOP_AT) {
setState(‘is-ended’);
} else {
setState(‘is-paused’);
}
});
video.addEventListener(‘ended’, function(){
// Certains navigateurs déclenchent ‘ended’ uniquement à fin réelle.
// On force l’arrêt à STOP_AT si la durée réelle STOP_AT) {
try { video.currentTime = STOP_AT; } catch(e) {}
}
try { video.pause(); } catch(e) {}
setState(‘is-ended’);
});
// Bouton relance depuis 0 mais coupe à STOP_AT
if (btn) {
btn.addEventListener(‘click’, function(){
try {
video.currentTime = 0;
var p = video.play();
if (p && typeof p.catch === ‘function’) {
p.catch(function(){
video.muted = true;
video.setAttribute(‘muted’,”);
video.setAttribute(‘playsinline’,”);
video.play().catch(function(){});
});
}
} catch(e) {}
});
}
// Afficher le layer quand la vidéo est prête (avec fallback)
var onReady = function () { showLayer(); cleanupReady(); };
function cleanupReady() {
video.removeEventListener(‘canplay’, onReady);
video.removeEventListener(‘loadeddata’, onReady);
}
video.addEventListener(‘canplay’, onReady);
video.addEventListener(‘loadeddata’, onReady);
setTimeout(showLayer, 3000); // secours si l’événement ne vient pas
// État initial selon la vidéo
if (video.ended || video.currentTime >= STOP_AT) {
try { video.currentTime = STOP_AT; } catch(e) {}
try { video.pause(); } catch(e) {}
setState(‘is-ended’);
} else if (video.paused) {
setState(‘is-paused’);
} else {
setState(‘is-playing’);
}
// Nettoyage si jamais le container est démonté
document.addEventListener(‘visibilitychange’, function(){
if (document.hidden && clampTimer) {
clearInterval(clampTimer);
clampTimer = null;
}
});
}
document.addEventListener(‘DOMContentLoaded’, initLayerVideo);
})();
/* Container existant : plein écran, fond bleu au chargement */
#LayerVideo{
position:relative;
min-height:100vh;
background:#163454 !important;
overflow:hidden;
}
/* Wrapper masqué (on applique le mask sur ce wrapper, pas sur
/* Masque SVG centré */
mask-image:url(“https://easydoorsystem.com/assets/siteuploads/2025/10/gear-eds.svg”);
mask-repeat:no-repeat;
mask-position:center center;
mask-size:0 0;
-webkit-mask-image:url(“https://easydoorsystem.com/assets/siteuploads/2025/10/gear-eds.svg”);
-webkit-mask-repeat:no-repeat;
-webkit-mask-position:center center;
-webkit-mask-size:0 0;
will-change:opacity,mask-size,-webkit-mask-size;
}
/* La vidéo prend 100% du wrapper, en cover */
#LayerVideo .lv-wrap > video{
position:absolute;
inset:0;
display:block;
width:100% !important;
height:100% !important;
object-fit:cover;
max-width:none !important;
max-height:none !important;
}
/* Déclencheur global (ajouté sur #LayerVideo) */
#LayerVideo.lv-animating .lv-wrap{
opacity:1;
animation:lvRevealMask 4s cubic-bezier(.2,.7,.2,1) forwards;
}
/* Animation : part de 0, couvre tout (vmax garantit LxH) */
@keyframes lvRevealMask{
0% { mask-size:0vmax; -webkit-mask-size:0vmax; }
60% { mask-size:130vmax; -webkit-mask-size:130vmax; }
100% { mask-size:200vmax; -webkit-mask-size:200vmax; }
}
/* Accessibilité */
@media (prefers-reduced-motion:reduce){
#LayerVideo.lv-animating .lv-wrap{
animation:none !important;
mask-size:200vmax !important;
-webkit-mask-size:200vmax !important;
opacity:1 !important;
}
}
/* Loader 0→100% au-dessus du fond bleu (derrière la vidéo révélée) */
#LayerVideo .lv-loader{
position:absolute;
inset:0;
display:grid;
place-items:center;
background:#163454;
color:#d0d6dd;
z-index:5;
transition:opacity .35s ease,visibility .35s ease;
}
#LayerVideo .lv-loader__inner{
font-family:Montserrat,system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;
font-weight:400;
font-size: 18px;
letter-spacing:.04em;
text-transform:uppercase;
text-align:center;
line-height:1;
}
#LayerVideo .lv-loader__label{
display:block;
font-size:clamp(12px,1.4vw,16px);
opacity:.85;
margin-bottom:.6em;
}
#LayerVideo .lv-loader__percent{
display:block;
font-size:clamp(32px,8vw,96px);
}
#LayerVideo.lv-animating .lv-loader{
opacity:0; visibility:hidden;
}
/**
* Loader 0→100 % puis révélation vidéo via masque SVG appliqué à un WRAPPER,
* pour éviter les bugs de sizing de
// Crée/insère le loader si absent
var loader = container.querySelector(‘.lv-loader’);
if(!loader){
loader = document.createElement(‘div’);
loader.className = ‘lv-loader’;
loader.innerHTML = ‘
Loading0%
‘;
container.appendChild(loader);
}
var percentEl = loader.querySelector(‘.lv-loader__percent’);
var supportsMask = (window.CSS && (CSS.supports(‘mask-image’,’url(#)’) || CSS.supports(‘-webkit-mask-image’,’url(#)’)));
var tries=0, maxTries=50; // ~5s pour trouver la vidéo si lazy Avada
var started=false, armed=false, intervalId=null, startTs=null;
var maxWaitMs=15000; // filet de sécu
function findAndWrapVideo(){
var video = container.querySelector(‘video’);
if(!video){
if(tries++=99) return true;
if(video.readyState>=4) return true; // HAVE_ENOUGH_DATA
return false;
}
function setupLoaderAndStart(video, wrap){
if(started) return;
started = true; armed = true; startTs = Date.now();
var simPct = 0;
function tick(){
if(!armed) return clearInterval(intervalId);
var realPct = bufferedPercent(video);
var showPct;
if(realPct===null){
var elapsed = Date.now()-startTs;
var target = Math.min(95, Math.round((elapsed/8000)*95)); // 0→95% ~8s
simPct = Math.max(simPct, target);
showPct = simPct;
}else{
simPct = Math.max(simPct, realPct);
showPct = simPct;
}
percentEl.textContent = showPct+’%’;
var timeoutReached = (Date.now()-startTs)>maxWaitMs;
if(isFullyBuffered(video) || timeoutReached){
percentEl.textContent = ‘100%’;
armed = false; clearInterval(intervalId);
// Start anim (one-shot)
requestAnimationFrame(function(){
container.classList.add(‘lv-animating’);
});
}
}
intervalId = setInterval(tick,120);
video.addEventListener(‘progress’, tick);
video.addEventListener(‘loadedmetadata’, tick);
video.addEventListener(‘canplaythrough’, tick);
// Nettoyage: retirer le mask du wrapper en fin d’animation
wrap.addEventListener(‘animationend’, function onEnd(){
wrap.removeEventListener(‘animationend’, onEnd);
try{
wrap.style.maskImage=’none’;
wrap.style.webkitMaskImage=’none’;
}catch(e){}
// Le loader est déjà masqué via .lv-animating
});
// Fallback si mask non supporté : le wrapper sert juste de conteneur, on fait un fade-in (opacity gérée)
if(!supportsMask){
setTimeout(function(){ wrap.style.opacity=’1′; }, 50);
}
}
if(document.readyState===’complete’ || document.readyState===’interactive’){
setTimeout(findAndWrapVideo,0);
}else{
document.addEventListener(‘DOMContentLoaded’, findAndWrapVideo);
}
})();