center front and back pages
Hunter
Monday, February 2nd, 2026 at 6:48 PM
2 let isAnimating = false;
3 let currentSpreadIndex = 0;
4 let pendingFlipQueue = [];
5 +let bookContainer = null;
6
7 // Get animation state
8 export function getIsAnimating() {
27 // Create the book structure
28 const book = doc.createElement('div');
29 book.className = 'zine-book';
30 + bookContainer = book;
31
32 // Create all leaves (page pairs)
33 PAGE_LEAVES.forEach((leaf, index) => {
67
68 // Set initial state - all leaves closed, showing front cover
69 updateLeafStates(0, doc);
70 + updateBookPosition(0, false);
71 +}
72 +
73 +// Update the book container horizontal position based on spread
74 +// Spreads 0 and 4 (single pages) should be centered, others at normal position
75 +function updateBookPosition(spreadIndex, animated = true) {
76 + if (!bookContainer) return;
77 +
78 + // Spread 0 (front cover): single right page, shift left to center
79 + // Spread 4 (back cover): single left page, shift right to center
80 + let shiftAmount = '0in';
81 + if (spreadIndex === 0) {
82 + shiftAmount = '-1.375in'; // Shift left by half a page width
83 + } else if (spreadIndex === 4) {
84 + shiftAmount = '1.375in'; // Shift right by half a page width
85 + }
86 +
87 + if (animated) {
88 + bookContainer.style.transition = 'transform 0.6s cubic-bezier(0.645, 0.045, 0.355, 1.000)';
89 + } else {
90 + bookContainer.style.transition = 'none';
91 + }
92 +
93 + // Preserve any existing scale from scaleSpreadToFit
94 + const currentTransform = bookContainer.style.transform || '';
95 + const scaleMatch = currentTransform.match(/scale\([^)]+\)/);
96 + const scale = scaleMatch ? scaleMatch[0] : '';
97 +
98 + bookContainer.style.transform = scale ? `translateX(${shiftAmount}) ${scale}` : `translateX(${shiftAmount})`;
99 +
100 + // Remove transition after animation completes
101 + if (animated) {
102 + setTimeout(() => {
103 + bookContainer.style.transition = '';
104 + }, 600);
105 + }
106 }
107
108 // Update which leaves are open/closed based on current spread
150 isAnimating = true;
151 currentSpreadIndex = toSpread;
152
153 + // Update book position synchronously with the flip animation
154 + updateBookPosition(toSpread, true);
155 +
156 const direction = toSpread > fromSpread ? 'forward' : 'backward';
157 const leaves = doc.querySelectorAll('.zine-leaf');
158
252 export function setSpreadImmediate(spreadIndex, doc) {
253 currentSpreadIndex = spreadIndex;
254 updateLeafStates(spreadIndex, doc);
255 + updateBookPosition(spreadIndex, false);
256 }
72 const scaleX = (vw - 40) / spreadWidthPx;
73 const scaleY = (vh - 40) / spreadHeightPx;
74 const scale = Math.min(scaleX, scaleY);
- bookContainer.style.transform = `scale(${scale})`;
75 +
76 + // Preserve any existing translateX from book positioning
77 + const currentTransform = bookContainer.style.transform || '';
78 + const translateMatch = currentTransform.match(/translateX\([^)]+\)/);
79 + const translateX = translateMatch ? translateMatch[0] : '';
80 +
81 + bookContainer.style.transform = translateX ? `${translateX} scale(${scale})` : `scale(${scale})`;
82 }