spread-navigation.js (3.1 KB)
1 import { SPREADS } from './constants.js'; 2 3 // State 4 let currentSpread = 0; 5 let isFullscreen = false; 6 7 // Get current spread index 8 export function getCurrentSpread() { 9 return currentSpread; 10 } 11 12 // Set current spread index 13 export function setCurrentSpread(index) { 14 currentSpread = index; 15 } 16 17 // Get fullscreen state 18 export function getIsFullscreen() { 19 return isFullscreen; 20 } 21 22 // Set fullscreen state 23 export function setIsFullscreen(value) { 24 isFullscreen = value; 25 } 26 27 // Update spread indicator and button states 28 export function updateSpreadIndicator() { 29 const indicator = document.getElementById('spreadIndicator'); 30 const prevBtn = document.getElementById('prevSpread'); 31 const nextBtn = document.getElementById('nextSpread'); 32 33 indicator.textContent = SPREADS[currentSpread].label; 34 prevBtn.disabled = currentSpread === 0; 35 nextBtn.disabled = currentSpread === SPREADS.length - 1; 36 } 37 38 // Navigate between spreads 39 export function navigateSpread(delta, updatePreviewCallback) { 40 const newSpread = currentSpread + delta; 41 if (newSpread >= 0 && newSpread < SPREADS.length) { 42 currentSpread = newSpread; 43 updateSpreadIndicator(); 44 45 // Try to animate if flip mode is enabled 46 const preview = document.getElementById('preview'); 47 try { 48 const doc = preview.contentDocument; 49 const container = doc?._zineContainer; 50 const flipModeEnabled = doc?._flipModeEnabled; 51 52 if (container && flipModeEnabled) { 53 // Dynamic import to avoid circular dependency 54 import('./spread-layout.js').then(({ navigateToSpread }) => { 55 navigateToSpread(container, newSpread, doc, true, () => { 56 // Refocus preview so keyboard navigation continues to work 57 preview.focus(); 58 }); 59 }); 60 } else { 61 updatePreviewCallback(); 62 preview.focus(); 63 } 64 } catch (e) { 65 // Fallback to regular update 66 updatePreviewCallback(); 67 preview.focus(); 68 } 69 } 70 } 71 72 // Fullscreen toggle 73 export function toggleFullscreen() { 74 isFullscreen = !isFullscreen; 75 const editorPane = document.querySelector('.editor-pane'); 76 const previewPane = document.querySelector('.preview-pane'); 77 const preview = document.getElementById('preview'); 78 79 if (isFullscreen) { 80 previewPane.classList.add('fullscreen'); 81 editorPane.classList.add('hidden'); 82 } else { 83 previewPane.classList.remove('fullscreen'); 84 editorPane.classList.remove('hidden'); 85 } 86 87 try { 88 const toggleButton = preview.contentDocument.getElementById('fullscreenToggle'); 89 if (toggleButton) { 90 toggleButton.title = isFullscreen ? 'Exit fullscreen' : 'Toggle fullscreen'; 91 } 92 } catch (e) {} 93 94 // Trigger resize after layout updates so scaleToFit() recalculates 95 requestAnimationFrame(() => { 96 try { 97 preview.contentWindow.dispatchEvent(new Event('resize')); 98 } catch (e) {} 99 }); 100 } 101 102 // Initialize spread navigation UI 103 export function initializeSpreadNav(navigateCallback) { 104 document.getElementById('prevSpread').addEventListener('click', () => navigateCallback(-1)); 105 document.getElementById('nextSpread').addEventListener('click', () => navigateCallback(1)); 106 updateSpreadIndicator(); 107 }