diff --git a/src/constants/EventTypes.ts b/src/constants/EventTypes.ts index 654a8f7..57db036 100644 --- a/src/constants/EventTypes.ts +++ b/src/constants/EventTypes.ts @@ -25,6 +25,7 @@ export const EventTypes = { WEEK_CHANGED: 'calendar:weekchanged', WEEK_INFO_UPDATED: 'calendar:weekinfoupdated', WEEK_CONTENT_RENDERED: 'calendar:weekcontentrendered', + NAVIGATION_ANIMATION_COMPLETE: 'calendar:navigationanimationcomplete', NAV_PREV: 'calendar:navprev', NAV_NEXT: 'calendar:navnext', NAV_TODAY: 'calendar:navtoday', diff --git a/src/managers/NavigationManager.ts b/src/managers/NavigationManager.ts index ea1ff73..2bdfb5f 100644 --- a/src/managers/NavigationManager.ts +++ b/src/managers/NavigationManager.ts @@ -152,46 +152,59 @@ export class NavigationManager { // Render new content for target week this.renderWeekContent(newGrid, targetWeek); - // Animate transition (POC animation) - requestAnimationFrame(() => { - // Slide out current grid - (currentGrid as HTMLElement).style.transform = direction === 'next' ? 'translateX(-100%)' : 'translateX(100%)'; - (currentGrid as HTMLElement).style.opacity = '0.5'; + // Animate transition using Web Animations API + const slideOutAnimation = (currentGrid as HTMLElement).animate([ + { transform: 'translateX(0)', opacity: '1' }, + { transform: direction === 'next' ? 'translateX(-100%)' : 'translateX(100%)', opacity: '0.5' } + ], { + duration: 400, + easing: 'ease-in-out', + fill: 'forwards' + }); + + const slideInAnimation = newGrid.animate([ + { transform: direction === 'next' ? 'translateX(100%)' : 'translateX(-100%)' }, + { transform: 'translateX(0)' } + ], { + duration: 400, + easing: 'ease-in-out', + fill: 'forwards' + }); + + // Handle animation completion + slideInAnimation.addEventListener('finish', () => { + // Cleanup: Remove all old grids except the new one + const allGrids = container.querySelectorAll('swp-grid-container'); + for (let i = 0; i < allGrids.length - 1; i++) { + allGrids[i].remove(); + } + + // Reset positioning + newGrid.style.position = 'relative'; - // Cleanup: Remove all old grids except the new one after animation - setTimeout(() => { - const allGrids = container.querySelectorAll('swp-grid-container'); - // Keep only the newest grid (last one), remove all others - for (let i = 0; i < allGrids.length - 1; i++) { - allGrids[i].remove(); - } - }, 450); + // Update state + this.currentWeek = new Date(targetWeek); + this.animationQueue--; - // Slide in new grid - newGrid.style.transform = 'translateX(0)'; + // If this was the last queued animation, ensure we're in sync + if (this.animationQueue === 0) { + this.currentWeek = new Date(this.targetWeek); + } - // Wait for new grid animation to complete before updating state - setTimeout(() => { - newGrid.style.position = 'relative'; - - // Only now is the animation truly complete - this.currentWeek = new Date(targetWeek); - this.animationQueue--; - - // If this was the last queued animation, ensure we're in sync - if (this.animationQueue === 0) { - this.currentWeek = new Date(this.targetWeek); - } - - // Update week info and notify other managers - this.updateWeekInfo(); - this.eventBus.emit(EventTypes.WEEK_CHANGED, { - weekStart: this.currentWeek, - weekEnd: DateUtils.addDays(this.currentWeek, 6) - }); - - console.log(`NavigationManager: Completed ${direction} animation`); - }, 400); // Wait for slide-in animation to complete + // Update week info and notify other managers + this.updateWeekInfo(); + this.eventBus.emit(EventTypes.WEEK_CHANGED, { + weekStart: this.currentWeek, + weekEnd: DateUtils.addDays(this.currentWeek, 6) + }); + + // Emit animation complete event for ScrollManager + this.eventBus.emit(EventTypes.NAVIGATION_ANIMATION_COMPLETE, { + direction, + weekStart: this.currentWeek + }); + + console.log(`NavigationManager: Completed ${direction} animation`); }); } diff --git a/src/managers/ScrollManager.ts b/src/managers/ScrollManager.ts index 8d807af..aa53a5e 100644 --- a/src/managers/ScrollManager.ts +++ b/src/managers/ScrollManager.ts @@ -33,9 +33,13 @@ export class ScrollManager { } private subscribeToEvents(): void { + // Handle navigation animation completion - sync time axis position + eventBus.on(EventTypes.NAVIGATION_ANIMATION_COMPLETE, () => { + console.log('ScrollManager: Navigation animation complete'); + this.syncTimeAxisPosition(); + this.setupScrolling(); + }); - // Handle new period shown - //we need to subscribe to appropriate event and then call setupScrolling() again // Handle window resize window.addEventListener('resize', () => {