From 3f5540712b56e55311604ce16a1043250772d1ab Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:23:46 -0400 Subject: [PATCH] fix(book): stop double-offsetting cover layers in the preview composite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The earlier cover-preview commit assumed layers were stored in panel-local coordinates (0..trimW relative to their panel's trim corner). They're not. Cover layers are appended directly to #layerOverlay (renderLayers, ~line 22344: 'el.style.left = inches(layer.x)'), which lives inside #sheet, so layer.x is sheet-absolute: a back layer's x already starts at >= bleed, a front layer's x already starts at >= bleed + trimW + spineW (targetBounds() seeds them there at creation time). Adding backX / spineX / frontX in the preview shifted every layer twice — front cover content slid off the right edge of the canvas, spine content drifted onto front, back content drifted onto spine. Fix: just remap target to 'canvas' and pass x / y through. The panel-offset variables are kept (renamed in scope) only for the overlay's fold-line and label positioning, which IS in absolute spread coordinates. The 'spec backfill' from the prior commit still stands — defensive against undefined coverHasBack / coverHasSpine on legacy state — but the visible misalignment in the preview vs. the editor was this coordinate-system mismatch. Co-Authored-By: Claude Opus 4.7 --- src/index.html | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/index.html b/src/index.html index 1ad78d0..e7ec03f 100644 --- a/src/index.html +++ b/src/index.html @@ -12776,36 +12776,33 @@ // Spread preview. Paint the actual cover layers into a single // composite canvas the size of the full wrap-around spread, // overlaid with subtle panel labels + fold-line dividers + the - // red trim guide. Layers are stored in panel-local space - // (book-cover-back / book-spine / book-cover-front, each at - // x=0 = left edge of that panel's trim area), so we remap each - // layer's target to 'canvas' and add the panel's offset within - // the spread + the outer bleed. + // red trim guide. IMPORTANT: cover layers store x / y in + // sheet-absolute coordinates (see renderLayers at ~22344 — the + // layer DOM is appended directly to #layerOverlay, not inside + // the slot div), so a back-panel layer's x already includes + // the bleed offset, and a front-panel layer's x already + // includes bleed + trimW + spineW. We only need to remap the + // target to 'canvas' so the preview helper's flat-canvas filter + // accepts the layer — no extra offset. const previewMaxPx = 720; const pxPerIn = totalW > 0 ? Math.min(previewMaxPx / totalW, 60) : 60; const renderWidth = Math.max(40, Math.round(totalW * pxPerIn)); wrap.innerHTML = ''; + // Panel boundary positions within the spread (sheet-absolute, + // in inches). Used only for the overlay (fold lines + labels); + // layer positions are already sheet-absolute and don't need + // these added. const backX = bleed; const spineX = bleed + (hasBack ? trimW : 0); const frontX = bleed + (hasBack ? trimW : 0) + (hasSpine ? spineW : 0); - const panelY = bleed; const compositeLayers = []; for (const l of (state.layers || [])) { if (l.hidden) continue; const t = String(l.target || ''); - let xo, yo; - if (t === 'book-cover-back' && hasBack) { xo = backX; yo = panelY; } - else if (t === 'book-spine' && hasSpine) { xo = spineX; yo = panelY; } - else if (t === 'book-cover-front') { xo = frontX; yo = panelY; } - else continue; - compositeLayers.push({ - ...l, - target: 'canvas', - x: (Number(l.x) || 0) + xo, - y: (Number(l.y) || 0) + yo, - }); + if (t !== 'book-cover-back' && t !== 'book-spine' && t !== 'book-cover-front') continue; + compositeLayers.push({ ...l, target: 'canvas' }); } compositeLayers.sort((a, b) => (a.z || 0) - (b.z || 0));