/* ================================================ Shoe Showcase – Interactive Mouse-Driven Animation ================================================ - Background panels expand/contract based on mouse X - Phone mockups fade in/out (only phones, text stays) - On mouse leave → smoothly resets to 50/50 ================================================ */ document.addEventListener('DOMContentLoaded', () => { const showcase = document.getElementById('showcase'); const bgRed = document.getElementById('bg-red'); const bgBlack = document.getElementById('bg-black'); const phoneRed = document.getElementById('phone-red'); const phoneBlack = document.getElementById('phone-black'); let targetRatio = 0.5; let currentRatio = 0.5; const LERP_SPEED = 0.1; function lerp(a, b, t) { return a + (b - a) * t; } function clamp(v, lo, hi) { return Math.min(hi, Math.max(lo, v)); } /* ---- mouse tracking ---- */ showcase.addEventListener('mousemove', (e) => { const rect = showcase.getBoundingClientRect(); targetRatio = clamp((e.clientX - rect.left) / rect.width, 0, 1); }); showcase.addEventListener('mouseleave', () => { targetRatio = 0.5; }); /* ---- animation loop ---- */ function animate() { currentRatio = lerp(currentRatio, targetRatio, LERP_SPEED); const r = currentRatio; /* 1. Background panel flex (full-width decorative) */ const redFlex = lerp(3.5, 0.3, r); const blackFlex = lerp(0.3, 3.5, r); bgRed.style.flex = redFlex; bgBlack.style.flex = blackFlex; /* 2. Phone mockup scale / opacity / translate */ const bias = (0.5 - r) * 2; // +1 red, -1 black const redScale = 1 + clamp(bias, 0, 1) * 0.3; const redOpacity = clamp(1 + bias * 3, 0, 1); const redShiftX = clamp(bias, 0, 1) * 60; const blackScale = 1 + clamp(-bias, 0, 1) * 0.3; const blackOpacity = clamp(1 - bias * 3, 0, 1); const blackShiftX = clamp(-bias, 0, 1) * -60; phoneRed.style.transform = `scale(${redScale}) translateX(${redShiftX}px)`; phoneRed.style.opacity = redOpacity; phoneBlack.style.transform = `scale(${blackScale}) translateX(${blackShiftX}px)`; phoneBlack.style.opacity = blackOpacity; /* 3. Text always stays visible — no opacity changes */ requestAnimationFrame(animate); } animate(); });