commit 191e1d1a0b13d105050cd71f5b93249877700bfa
parent 9e3323f1342ea8c2fc5e2116d4a4b949a40ed270
Author: Hunter
Date: Mon, 2 Feb 2026 18:48:25 -0500
center front and back pages
Diffstat:
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/resources/page-flip-animation.js b/resources/page-flip-animation.js
@@ -2,6 +2,7 @@
let isAnimating = false;
let currentSpreadIndex = 0;
let pendingFlipQueue = [];
+let bookContainer = null;
// Get animation state
export function getIsAnimating() {
@@ -26,6 +27,7 @@ export function initPageFlip(container, doc) {
// Create the book structure
const book = doc.createElement('div');
book.className = 'zine-book';
+ bookContainer = book;
// Create all leaves (page pairs)
PAGE_LEAVES.forEach((leaf, index) => {
@@ -65,6 +67,42 @@ export function initPageFlip(container, doc) {
// Set initial state - all leaves closed, showing front cover
updateLeafStates(0, doc);
+ updateBookPosition(0, false);
+}
+
+// Update the book container horizontal position based on spread
+// Spreads 0 and 4 (single pages) should be centered, others at normal position
+function updateBookPosition(spreadIndex, animated = true) {
+ if (!bookContainer) return;
+
+ // Spread 0 (front cover): single right page, shift left to center
+ // Spread 4 (back cover): single left page, shift right to center
+ let shiftAmount = '0in';
+ if (spreadIndex === 0) {
+ shiftAmount = '-1.375in'; // Shift left by half a page width
+ } else if (spreadIndex === 4) {
+ shiftAmount = '1.375in'; // Shift right by half a page width
+ }
+
+ if (animated) {
+ bookContainer.style.transition = 'transform 0.6s cubic-bezier(0.645, 0.045, 0.355, 1.000)';
+ } else {
+ bookContainer.style.transition = 'none';
+ }
+
+ // Preserve any existing scale from scaleSpreadToFit
+ const currentTransform = bookContainer.style.transform || '';
+ const scaleMatch = currentTransform.match(/scale\([^)]+\)/);
+ const scale = scaleMatch ? scaleMatch[0] : '';
+
+ bookContainer.style.transform = scale ? `translateX(${shiftAmount}) ${scale}` : `translateX(${shiftAmount})`;
+
+ // Remove transition after animation completes
+ if (animated) {
+ setTimeout(() => {
+ bookContainer.style.transition = '';
+ }, 600);
+ }
}
// Update which leaves are open/closed based on current spread
@@ -112,6 +150,9 @@ function executePageFlip(fromSpread, toSpread, container, doc, onComplete) {
isAnimating = true;
currentSpreadIndex = toSpread;
+ // Update book position synchronously with the flip animation
+ updateBookPosition(toSpread, true);
+
const direction = toSpread > fromSpread ? 'forward' : 'backward';
const leaves = doc.querySelectorAll('.zine-leaf');
@@ -211,4 +252,5 @@ export function animatePageFlip(fromSpread, toSpread, container, doc, onComplete
export function setSpreadImmediate(spreadIndex, doc) {
currentSpreadIndex = spreadIndex;
updateLeafStates(spreadIndex, doc);
+ updateBookPosition(spreadIndex, false);
}
diff --git a/resources/spread-layout.js b/resources/spread-layout.js
@@ -72,5 +72,11 @@ export function scaleSpreadToFit(container, doc, bottomPadding = 0) {
const scaleX = (vw - 40) / spreadWidthPx;
const scaleY = (vh - 40) / spreadHeightPx;
const scale = Math.min(scaleX, scaleY);
- bookContainer.style.transform = `scale(${scale})`;
+
+ // Preserve any existing translateX from book positioning
+ const currentTransform = bookContainer.style.transform || '';
+ const translateMatch = currentTransform.match(/translateX\([^)]+\)/);
+ const translateX = translateMatch ? translateMatch[0] : '';
+
+ bookContainer.style.transform = translateX ? `${translateX} scale(${scale})` : `scale(${scale})`;
}