diff --git a/js/intro-scene.js b/js/intro-scene.js index a618a78..05ddd31 100644 --- a/js/intro-scene.js +++ b/js/intro-scene.js @@ -65,26 +65,45 @@ loader.load( ); /* ── Souris ───────────────────────────────────────────────────────────── - - mouseX, mouseY : 0..1 normalisés - - Sur écran sans souris (touch/mobile), valeur lente d'auto-scroll + La souris fait AVANCER l'avion sur sa trajectoire : on accumule la + distance parcourue par le curseur. Une fois que l'avion est sorti à + droite (progress = 1), il reste sorti — la souris ne le ramène pas. + + On garde aussi mouseX (0..1) pour la parallaxe légère de la photo. */ -const mouse = { tx: 0.0, ty: 0.5, x: 0.0, y: 0.5 }; +const FULL_DISTANCE = 3500; // pixels de souris pour traverser tout l'écran +const mouse = { + targetProgress: 0, // accumulé, croissant + progress: 0, // suit avec lerp + px: 0.5, py: 0.5 // dernier point connu (parallaxe fond) +}; +let lastX = null, lastY = null; window.addEventListener('mousemove', (e) => { - mouse.tx = Math.max(0, Math.min(1, e.clientX / window.innerWidth)); - mouse.ty = Math.max(0, Math.min(1, e.clientY / window.innerHeight)); -}, { passive: true }); - -/* Sur mobile : utilise l'orientation gamma (gauche-droite) si dispo */ -window.addEventListener('deviceorientation', (e) => { - if (e.gamma == null) return; - mouse.tx = Math.max(0, Math.min(1, (e.gamma + 30) / 60)); - if (e.beta != null) { - mouse.ty = Math.max(0, Math.min(1, (e.beta - 20) / 60)); + if (lastX !== null) { + const dx = e.clientX - lastX; + const dy = e.clientY - lastY; + mouse.targetProgress = Math.min(1, mouse.targetProgress + Math.hypot(dx, dy) / FULL_DISTANCE); } + lastX = e.clientX; lastY = e.clientY; + mouse.px = e.clientX / window.innerWidth; + mouse.py = e.clientY / window.innerHeight; +}, { passive: true }); + +/* Mobile : la rotation du device fait progresser l'avion */ +let lastGamma = null, lastBeta = null; +window.addEventListener('deviceorientation', (e) => { + if (e.gamma == null || e.beta == null) return; + if (lastGamma !== null) { + const dg = e.gamma - lastGamma; + const db = e.beta - lastBeta; + mouse.targetProgress = Math.min(1, mouse.targetProgress + Math.hypot(dg, db) / 90); + } + lastGamma = e.gamma; lastBeta = e.beta; + mouse.px = Math.max(0, Math.min(1, (e.gamma + 30) / 60)); + mouse.py = Math.max(0, Math.min(1, (e.beta - 20) / 60)); }, { passive: true }); -/* Variable CSS pour la parallaxe douce de la photo de fond */ const root = document.documentElement; /* ── Render loop ───────────────────────────────────────────────────────── */ @@ -93,34 +112,32 @@ const clock = new THREE.Clock(); function tick() { const t = clock.getElapsedTime(); - /* Lerp doux vers la cible souris */ - mouse.x += (mouse.tx - mouse.x) * 0.06; - mouse.y += (mouse.ty - mouse.y) * 0.06; + /* Lerp doux vers la cible (progrès cumulé) */ + mouse.progress += (mouse.targetProgress - mouse.progress) * 0.06; + const p = mouse.progress; - /* Mappe sur les variables CSS (parallaxe légère du fond) */ - root.style.setProperty('--mx', ((mouse.x - 0.5) * 2).toFixed(4)); - root.style.setProperty('--my', ((mouse.y - 0.5) * 2).toFixed(4)); + /* Variables CSS pour la parallaxe légère de la photo de fond */ + root.style.setProperty('--mx', ((mouse.px - 0.5) * 2).toFixed(4)); + root.style.setProperty('--my', ((mouse.py - 0.5) * 2).toFixed(4)); - /* Position de l'avion : - - mouse.x = 0 → arrive haut-gauche (hors champ) - - mouse.x = 0.5 → centré - - mouse.x = 1 → sortie en bas-droite (hors champ) + /* Trajectoire : + - p = 0 → arrive haut-gauche (hors champ) + - p = 0.5 → traverse au centre haut + - p = 1 → sortie à droite (hors champ) */ - const px = -16 + mouse.x * 32; // -16 à +16 - const py = 7 - mouse.x * 5; // descend de +7 à +2 (haut de l'écran) - /* Léger bobbing autonome pour qu'il reste vivant même sans bouger la souris */ + const px = -16 + p * 32; + const py = 7 - p * 5; const bob = Math.sin(t * 0.9) * 0.12; planeHolder.position.set(px, py + bob, 0); - /* Roulis : penche dans le sens du mouvement (mais tourne le nez vers la droite) */ - const targetRoll = -0.18 - (mouse.x - 0.5) * 0.25; // léger pivot quand on traverse - const targetPitch = -0.18 - mouse.x * 0.10; // légèrement piqué - const targetYaw = (mouse.x - 0.5) * 0.10; // soupçon de yaw - - planeHolder.rotation.z += (targetRoll - planeHolder.rotation.z) * 0.08; + /* Banking subtil — penche en pivotant */ + const targetRoll = -0.18 - (p - 0.5) * 0.25; + const targetPitch = -0.18 - p * 0.10; + const targetYaw = (p - 0.5) * 0.10; + planeHolder.rotation.z += (targetRoll - planeHolder.rotation.z) * 0.08; planeHolder.rotation.x += (targetPitch - planeHolder.rotation.x) * 0.08; - planeHolder.rotation.y += (targetYaw - planeHolder.rotation.y) * 0.08; + planeHolder.rotation.y += (targetYaw - planeHolder.rotation.y) * 0.08; renderer.render(scene, camera); requestAnimationFrame(tick);