(function(){ const lastAngles = { handXeno: 0, handQuantic: 0, handChronon: 0, handEonstrip: 0, handMegasequence: 0 }; function rotateHand(id, angle) { const el = document.getElementById(id); if (!el) return; const prev = lastAngles[id]; if (angle < prev) { const target = angle + 360; const handle = () => { el.removeEventListener('transitionend', handle); el.style.transition = 'none'; el.style.transform = `translateX(-50%) translateZ(0) rotate(${angle}deg)`; void el.offsetWidth; el.style.transition = ''; }; el.addEventListener('transitionend', handle, { once: true }); el.style.transform = `translateX(-50%) translateZ(0) rotate(${target}deg)`; } else { el.style.transform = `translateX(-50%) translateZ(0) rotate(${angle}deg)`; } lastAngles[id] = angle; } function animateSwipe(direction, onDone) { const grid = document.getElementById('eonstripGrid'); if (!grid) { onDone(); return; } grid.style.transition = 'none'; grid.style.transform = 'translateX(0)'; void grid.offsetWidth; grid.style.transition = 'transform 0.3s ease'; grid.style.transform = `translateX(${direction > 0 ? '-100%' : '100%'})`; function afterOut() { grid.removeEventListener('transitionend', afterOut); grid.style.transition = 'none'; grid.style.transform = `translateX(${direction > 0 ? '100%' : '-100%'})`; onDone(); void grid.offsetWidth; grid.style.transition = 'transform 0.3s ease'; grid.style.transform = 'translateX(0)'; } grid.addEventListener('transitionend', afterOut); } function animateDetailSwipe(direction, onDone) { const tl = document.getElementById('detailTimeline'); if (!tl) { onDone(); return; } tl.style.transition = 'none'; tl.style.transform = 'translateX(0)'; void tl.offsetWidth; tl.style.transition = 'transform 0.3s ease'; tl.style.transform = `translateX(${direction > 0 ? '-100%' : '100%'})`; function afterOut() { tl.removeEventListener('transitionend', afterOut); tl.style.transition = 'none'; tl.style.transform = `translateX(${direction > 0 ? '100%' : '-100%'})`; onDone(); void tl.offsetWidth; tl.style.transition = 'transform 0.3s ease'; tl.style.transform = 'translateX(0)'; } tl.addEventListener('transitionend', afterOut); } window.Animate = { rotateHand, animateSwipe, animateDetailSwipe }; })();