/* ================================================ Shoe Showcase – Interactive GSAP Animation ================================================ - Uses GSAP for smooth easing and interpolation ================================================ */ 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'); const contentLeft = document.getElementById('content-left'); const contentRight = document.getElementById('content-right'); function clamp(v, lo, hi) { return Math.min(hi, Math.max(lo, v)); } function lerp(a, b, t) { return a + (b - a) * t; } function animateToRatio(ratio) { // ratio is 0 (far left) to 1 (far right). Center is 0.5. // 1. Calculate flex values for background panels const redFlex = lerp(3.5, 0.3, ratio); const blackFlex = lerp(0.3, 3.5, ratio); // 2. Calculate bias for phones (+1 when red dominates, -1 when black dominates) const bias = (0.5 - ratio) * 2; 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; // 3. Animate using GSAP // Using overwrite: "auto" ensures that new mouse movements smoothly override old animations const animConfig = { duration: 0.5, ease: "power2.out", overwrite: "auto" }; gsap.to(bgRed, { flexGrow: redFlex, ...animConfig }); gsap.to(bgBlack, { flexGrow: blackFlex, ...animConfig }); gsap.to(phoneRed, { scale: redScale, x: redShiftX, opacity: redOpacity, ...animConfig }); gsap.to(phoneBlack, { scale: blackScale, x: blackShiftX, opacity: blackOpacity, ...animConfig }); gsap.to(contentLeft, { opacity: redOpacity, ...animConfig }); gsap.to(contentRight, { opacity: blackOpacity, ...animConfig }); } // Set initial center state gsap.set(bgRed, { flexGrow: 1 }); gsap.set(bgBlack, { flexGrow: 1 }); /* ---- Mouse tracking ---- */ showcase.addEventListener('mousemove', (e) => { const rect = showcase.getBoundingClientRect(); const ratio = clamp((e.clientX - rect.left) / rect.width, 0, 1); animateToRatio(ratio); }); // Spring back to center on leave showcase.addEventListener('mouseleave', () => { animateToRatio(0.5); }); });