diff --git a/css/parallax.css b/css/parallax.css index 6726f1f..d7a1d71 100644 --- a/css/parallax.css +++ b/css/parallax.css @@ -117,12 +117,23 @@ html, body { .layer-three { display: block; z-index: 2; } -/* ── BOUTON CTA centré ──────────────────────────────────────────────────── */ +/* ── BOUTON CTA centré ──────────────────────────────────────────────────── + État caché : positionné là où l'avion est au centre de sa course + (~27% au-dessus du centre du viewport), à scale ≈ 0. Quand le JS + ajoute la classe `.revealed` (au moment où l'avion atteint p ≥ 0.5), + les variables CSS basculent et le bouton « sort » de l'avion en + grossissant jusqu'à sa taille finale au centre. */ .cta-btn { + --cta-y: -27vh; /* offset vertical : 0 = centré */ + --cta-scale: 0.05; + --cta-opacity: 0; + position: absolute; top: 50%; left: 50%; - transform: translate(-50%, -50%); + transform: translate(-50%, calc(-50% + var(--cta-y))) scale(var(--cta-scale)); + opacity: var(--cta-opacity); + pointer-events: none; z-index: 10; display: inline-flex; align-items: center; @@ -142,12 +153,25 @@ html, body { 0 20px 60px rgba(197, 165, 90, 0.55), 0 0 0 0 rgba(197, 165, 90, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.45); - transition: box-shadow 0.32s cubic-bezier(0.2, 0.8, 0.2, 1), - transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1); + transition: + transform 1.2s cubic-bezier(0.34, 1.5, 0.64, 1), + opacity 0.5s ease 0.05s, + box-shadow 0.32s cubic-bezier(0.2, 0.8, 0.2, 1); } -.cta-btn:hover { - transform: translate(-50%, -50%) scale(1.04); +.cta-btn.revealed { + --cta-y: 0vh; + --cta-scale: 1; + --cta-opacity: 1; + pointer-events: auto; +} + +/* Hover seulement après la révélation, avec une transition rapide */ +.cta-btn.revealed:hover { + --cta-scale: 1.04; + transition: + transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1), + box-shadow 0.32s cubic-bezier(0.2, 0.8, 0.2, 1); box-shadow: 0 28px 75px rgba(197, 165, 90, 0.7), 0 0 0 12px rgba(197, 165, 90, 0.12), @@ -177,9 +201,12 @@ html, body { inset: -3px; border-radius: 50px; border: 2px solid rgba(197, 165, 90, 0.55); - animation: ctaPulse 2.8s ease-out infinite; + animation: none; /* halo dormant tant que le bouton n'est pas révélé */ pointer-events: none; } +.cta-btn.revealed::after { + animation: ctaPulse 2.8s ease-out 1s infinite; /* démarre après l'arrivée du bouton */ +} @keyframes ctaPulse { 0% { transform: scale(1); opacity: 0.7; } 100% { transform: scale(1.18); opacity: 0; } diff --git a/js/intro-scene.js b/js/intro-scene.js index 54f1957..067d9a1 100644 --- a/js/intro-scene.js +++ b/js/intro-scene.js @@ -239,6 +239,13 @@ window.addEventListener('deviceorientation', (e) => { const root = document.documentElement; +/* ── Révélation du CTA ───────────────────────────────────────────────── + Quand l'avion arrive au centre de l'écran (p ≥ 0.5), on bascule la + classe `.revealed` sur le bouton. La CSS gère l'animation (translate + du haut vers le centre + scale 0.05 → 1, ~1.2 s). */ +const ctaBtn = document.querySelector('.cta-btn'); +let ctaRevealed = false; + /* ── Render loop ───────────────────────────────────────────────────────── */ const clock = new THREE.Clock(); @@ -278,6 +285,13 @@ function tick() { } updateParcels(dt, t); + /* Au moment où l'avion atteint le centre, on déclenche la sortie du + CTA (l'animation CSS s'en occupe ensuite). One-shot. */ + if (!ctaRevealed && p >= 0.5) { + ctaRevealed = true; + ctaBtn?.classList.add('revealed'); + } + /* Avec nez à -X et up = +Y : - rotation.z = PITCH (négatif = nez en l'air) - rotation.x = ROLL