diff --git a/script.js b/script.js index 4218ebc..4c39260 100644 --- a/script.js +++ b/script.js @@ -890,8 +890,34 @@ function navigatePeriod(evt, direction) { step = 16**1; } - currentOffset += direction * step; - updateCalendar(); + animateSwipe(direction, () => { + currentOffset += direction * step; + updateCalendar(); + }); +} + +function animateSwipe(direction, onDone) { + const grid = document.getElementById('eonstripGrid'); + if (!grid) { onDone(); return; } + + // slide out + grid.style.transition = 'transform 0.3s ease'; + grid.style.transform = `translateX(${direction > 0 ? '-100%' : '100%'})`; + + function afterOut() { + grid.removeEventListener('transitionend', afterOut); + // prepare new position off-screen on the other side + grid.style.transition = 'none'; + grid.style.transform = `translateX(${direction > 0 ? '100%' : '-100%'})`; + onDone(); + // force reflow to apply position instantly + void grid.offsetWidth; + // slide in with transition + grid.style.transition = 'transform 0.3s ease'; + grid.style.transform = 'translateX(0)'; + } + + grid.addEventListener('transitionend', afterOut); } function goToNow() { diff --git a/style.css b/style.css index e650381..fdf8f5c 100644 --- a/style.css +++ b/style.css @@ -175,6 +175,7 @@ padding: 20px; backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); + overflow: hidden; } .calendar-header { @@ -189,6 +190,9 @@ grid-template-columns: repeat(4, 1fr); gap: 15px; margin-bottom: 20px; + transform: translateX(0); + transition: transform 0.3s ease; + will-change: transform; } .eonstrip-card { @@ -353,4 +357,7 @@ .eonstrip-grid { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); + transform: translateX(0); + transition: transform 0.3s ease; + will-change: transform; }