mirror of
https://github.com/PR0M3TH3AN/Artstr-Studio.git
synced 2026-11-02 11:40:39 +00:00
fix(book): Edit cover now actually shows the cover scaffolding
Two bugs prevented the book cover editor from rendering anything
visible:
1. body.template-book had an unconditional 'display:none !important'
on .coverOnly (and on .bleedFill, .trimArea, .foldLine, .spineText),
so when editing-book-cover was set the slot boxes, fold lines, crop
marks, and trim guides stayed hidden. The hide rule now uses
:not(.editing-book-cover) for the cover scaffolding while still
unconditionally hiding the disc/jewel scaffolding (which never
belongs on a book cover).
2. The .slot positions are driven by --panel-w, --spine-w, --trim-h,
--bleed, --safe CSS custom properties. renderDimensions() was
writing DVD-cover state.* values into those for every render,
including in book cover mode — so even if the slots were visible
they would have been sized for the last DVD preset, not the book
spec. renderDimensions now writes book-spec values into the CSS
vars whenever state.book.editingCover is true, so the back / spine
/ front panels lay out at the book's trim with the spine derived
from page count × paper thickness.
For the asymmetric cases (coverHasBack=false or coverHasSpine=false),
a new applyBookCoverSlotLayout() helper writes inline left / width
overrides for the slot, trim, fold line, and crop-mark elements so
they sit in the right places. clearBookCoverSlotLayout() drops those
overrides whenever we leave cover edit mode so the CSS defaults take
back over. New body classes no-cover-back / no-cover-spine hide the
slot box for the missing panel.
Slot placeholders ('Enter back image URL' etc.) are hidden in book
cover edit mode — those belong to the DVD URL flow, not the book
cover layer system.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
1 parent
549d6a61d9
commit
3f5d244a8e
1 file changed
+120
-11
+120
-11
@@ -1683,15 +1683,36 @@
|
||||
body.template-book:not(.editing-book-page):not(.editing-book-cover) #layersFieldset,
|
||||
body.template-book:not(.editing-book-page):not(.editing-book-cover) #printExportRow,
|
||||
body.template-book:not(.editing-book-page):not(.editing-book-cover) .toolPalette,
|
||||
body.template-book .coverOnly,
|
||||
/* Hide DVD/disc/jewel-specific scaffolding in book mode, *except*
|
||||
when we're actively editing the book's cover spread — then we
|
||||
want the back/spine/front slot boxes, fold lines, crop marks,
|
||||
bleed fill and trim guide back, so the canvas looks like the
|
||||
DVD cover designer scaled to the book's spec. */
|
||||
body.template-book:not(.editing-book-cover) .coverOnly,
|
||||
body.template-book:not(.editing-book-cover) .bleedFill,
|
||||
body.template-book:not(.editing-book-cover) .trimArea,
|
||||
body.template-book:not(.editing-book-cover) .foldLine,
|
||||
body.template-book:not(.editing-book-cover) .spineText { display: none !important; }
|
||||
/* Disc + jewel scaffolding never belongs on a book cover. */
|
||||
body.template-book .diskLayer,
|
||||
body.template-book .jewelLayer,
|
||||
body.template-book .bleedFill,
|
||||
body.template-book .trimArea,
|
||||
body.template-book .foldLine,
|
||||
body.template-book .discSpineStrip,
|
||||
body.template-book .jewelSpineGuide,
|
||||
body.template-book .spineText { display: none !important; }
|
||||
body.template-book .jewelSpineGuide { display: none !important; }
|
||||
|
||||
/* When the book has no back panel / no spine, hide those slot
|
||||
boxes so the front sits alone (JS in renderDimensions positions
|
||||
it correctly via inline left/width overrides). */
|
||||
body.template-book.editing-book-cover.no-cover-back .slot.back { display: none !important; }
|
||||
body.template-book.editing-book-cover.no-cover-spine .slot.spine { display: none !important; }
|
||||
body.template-book.editing-book-cover.no-cover-spine .spineText { display: none !important; }
|
||||
body.template-book.editing-book-cover.no-cover-spine .foldLine { display: none !important; }
|
||||
|
||||
/* Slot placeholders ("Enter back image URL" etc.) belong to the
|
||||
DVD cover URL flow; book covers use the layer system instead.
|
||||
Replace the text in book-cover edit mode via data-label hints
|
||||
on the slot itself. */
|
||||
body.template-book.editing-book-cover .slot .placeholder { display: none !important; }
|
||||
|
||||
/* When editing the cover, hide the Pages-overview / Cover-summary
|
||||
panels so the wider canvas takes the room. */
|
||||
body.template-book.editing-book-cover #bookView { display: none; }
|
||||
@@ -14092,6 +14113,67 @@
|
||||
syncBookSidebarSummary();
|
||||
}
|
||||
|
||||
// Book cover edit mode reuses the DVD-style .slot.back / .slot.spine
|
||||
// / .slot.front scaffolding (positioned via --panel-w / --spine-w
|
||||
// CSS vars). The canonical book wrap (hasBack && hasSpine) lays out
|
||||
// correctly via the default CSS rules once those vars hold the
|
||||
// book's trim + spine. The asymmetric cases (no back, no spine)
|
||||
// need inline `left` / `width` overrides because the default rules
|
||||
// assume both panels are present.
|
||||
function applyBookCoverSlotLayout({ trimW, trimH, spineW, bleed, hasBack, hasSpine }) {
|
||||
const back = document.getElementById('slot-back');
|
||||
const spine = document.getElementById('slot-spine');
|
||||
const front = document.getElementById('slot-front');
|
||||
const trim = document.querySelector('.trimArea');
|
||||
const foldL = document.querySelector('.foldLine.left');
|
||||
const foldR = document.querySelector('.foldLine.right');
|
||||
const backW = hasBack ? trimW : 0;
|
||||
const sW = hasSpine ? spineW : 0;
|
||||
const totalTrimW = backW + sW + trimW;
|
||||
if (back) { back.style.left = inches(bleed); back.style.width = inches(trimW); }
|
||||
if (spine) { spine.style.left = inches(bleed + backW); spine.style.width = inches(spineW); }
|
||||
if (front) { front.style.left = inches(bleed + backW + sW); front.style.width = inches(trimW); }
|
||||
if (trim) { trim.style.left = inches(bleed); trim.style.width = inches(totalTrimW); }
|
||||
if (foldL) foldL.style.left = inches(bleed + backW);
|
||||
if (foldR) foldR.style.left = inches(bleed + backW + sW);
|
||||
// Crop marks anchor to the four outer corners of the trim.
|
||||
_setCropMark('.cm-tl-h', bleed - 0.24, bleed);
|
||||
_setCropMark('.cm-tl-v', bleed, bleed - 0.24);
|
||||
_setCropMark('.cm-tr-h', bleed + totalTrimW + 0.06, bleed);
|
||||
_setCropMark('.cm-tr-v', bleed + totalTrimW, bleed - 0.24);
|
||||
_setCropMark('.cm-bl-h', bleed - 0.24, bleed + trimH);
|
||||
_setCropMark('.cm-bl-v', bleed, bleed + trimH + 0.06);
|
||||
_setCropMark('.cm-br-h', bleed + totalTrimW + 0.06, bleed + trimH);
|
||||
_setCropMark('.cm-br-v', bleed + totalTrimW, bleed + trimH + 0.06);
|
||||
}
|
||||
function _setCropMark(sel, leftIn, topIn) {
|
||||
const el = document.querySelector(sel);
|
||||
if (!el) return;
|
||||
el.style.left = inches(leftIn);
|
||||
el.style.top = inches(topIn);
|
||||
}
|
||||
function clearBookCoverSlotLayout() {
|
||||
// Drop all inline overrides so the CSS defaults take over again
|
||||
// (used when leaving cover edit mode or switching to a non-book
|
||||
// template). Idempotent — safe to call on every render.
|
||||
const ids = ['slot-back', 'slot-spine', 'slot-front'];
|
||||
for (const id of ids) {
|
||||
const el = document.getElementById(id);
|
||||
if (!el) continue;
|
||||
el.style.left = '';
|
||||
el.style.width = '';
|
||||
}
|
||||
for (const sel of ['.trimArea', '.foldLine.left', '.foldLine.right',
|
||||
'.cm-tl-h', '.cm-tl-v', '.cm-tr-h', '.cm-tr-v',
|
||||
'.cm-bl-h', '.cm-bl-v', '.cm-br-h', '.cm-br-v']) {
|
||||
const el = document.querySelector(sel);
|
||||
if (!el) continue;
|
||||
el.style.left = '';
|
||||
el.style.top = '';
|
||||
el.style.width = '';
|
||||
}
|
||||
}
|
||||
|
||||
function renderDimensions() {
|
||||
if (state.appMode === 'designer') {
|
||||
const design = state.discDesign;
|
||||
@@ -14105,11 +14187,38 @@
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty('--sheet-w', inches(sheetW()));
|
||||
root.style.setProperty('--sheet-h', inches(sheetH()));
|
||||
root.style.setProperty('--panel-w', inches(state.panelW));
|
||||
root.style.setProperty('--trim-h', inches(state.trimH));
|
||||
root.style.setProperty('--spine-w', inches(state.spineW));
|
||||
root.style.setProperty('--bleed', inches(state.bleed));
|
||||
root.style.setProperty('--safe', inches(state.safe));
|
||||
// Book cover edit mode reuses the DVD-cover slot scaffolding
|
||||
// (.slot.back / .slot.spine / .slot.front + bleed + trim + crop
|
||||
// marks), so the CSS custom properties need to be book-spec
|
||||
// values rather than the DVD-cover state.* values. Spine width
|
||||
// re-derives from page count × paper thickness via
|
||||
// bookSpineWidthInches().
|
||||
if (state.templateMode === 'book' && state.book?.editingCover) {
|
||||
const s = state.book.spec || {};
|
||||
const trimW = Number(s.trimW) || 0;
|
||||
const trimH = Number(s.trimH) || 0;
|
||||
const bleed = Number(s.bleed) || 0;
|
||||
const safe = Number(s.safe) || 0.125;
|
||||
const hasBack = !!s.coverHasBack;
|
||||
const hasSpine = !!s.coverHasSpine;
|
||||
const spineW = hasSpine ? bookSpineWidthInches() : 0;
|
||||
root.style.setProperty('--panel-w', inches(trimW));
|
||||
root.style.setProperty('--trim-h', inches(trimH));
|
||||
root.style.setProperty('--spine-w', inches(spineW));
|
||||
root.style.setProperty('--bleed', inches(bleed));
|
||||
root.style.setProperty('--safe', inches(safe));
|
||||
document.body.classList.toggle('no-cover-back', !hasBack);
|
||||
document.body.classList.toggle('no-cover-spine', !hasSpine);
|
||||
applyBookCoverSlotLayout({ trimW, trimH, spineW, bleed, hasBack, hasSpine });
|
||||
} else {
|
||||
root.style.setProperty('--panel-w', inches(state.panelW));
|
||||
root.style.setProperty('--trim-h', inches(state.trimH));
|
||||
root.style.setProperty('--spine-w', inches(state.spineW));
|
||||
root.style.setProperty('--bleed', inches(state.bleed));
|
||||
root.style.setProperty('--safe', inches(state.safe));
|
||||
document.body.classList.remove('no-cover-back', 'no-cover-spine');
|
||||
clearBookCoverSlotLayout();
|
||||
}
|
||||
|
||||
const pageW = state.templateMode === 'cover' ? 11 : sheetW();
|
||||
const pageH = state.templateMode === 'cover' ? 8.5 : sheetH();
|
||||
|
||||
Reference in new issue
Block a user