fix(exam): keep region shapes overlaid on PDF in setup canvas
Some checks failed
app-ci-deploy / test-build-deploy (push) Has been cancelled
Some checks failed
app-ci-deploy / test-build-deploy (push) Has been cancelled
Three z-order fixes in ExamTemplateSetupPage: 1. loadShapes: early-return before deletion when models is empty, so seed guide shapes aren't wiped for a fresh template that has no saved regions yet. 2. Incremental PDF loading (onPageReady): replace per-page sendToBack (unreliable when all shapes are moving — reorderToBack no-ops) with bringToFront on existing domain shapes after each page is added. 3. Final load sequence: call bringDomainShapesToFront after syncPdfPages + loadShapes to guarantee correct z-order regardless of how tldraw's fractional indexer placed newly created shapes. Also called from onMount for the same reason. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3389fdcb5b
commit
15a519748d
@ -88,10 +88,15 @@ function modelFromTLShape(shape: TLShape): ExamCanvasShapeModel | null {
|
||||
}
|
||||
}
|
||||
|
||||
function bringDomainShapesToFront(editor: Editor) {
|
||||
const ids = editor.getCurrentPageShapes().filter((s) => !!shapeTypeToKind(s.type)).map((s) => s.id)
|
||||
if (ids.length) try { editor.bringToFront(ids as any) } catch { /* */ }
|
||||
}
|
||||
|
||||
function loadShapes(editor: Editor, models: ExamCanvasShapeModel[]) {
|
||||
if (!models.length) return
|
||||
const existing = editor.getCurrentPageShapes().filter((s) => shapeTypeToKind(s.type)).map((s) => s.id)
|
||||
if (existing.length) editor.deleteShapes(existing)
|
||||
if (!models.length) return
|
||||
editor.createShapes(models.map((m) => ({
|
||||
id: createShapeId(m.id),
|
||||
type: SHAPE_TYPES[m.kind],
|
||||
@ -117,8 +122,7 @@ function syncPdfPages(editor: Editor, pages: PdfPageImage[]) {
|
||||
props: { w: geometry.w, h: geometry.h, src: page.src, pageNumber: geometry.pageNumber },
|
||||
} as any
|
||||
}))
|
||||
const ids = geometries.map((geometry) => createShapeId(PDF_PAGE_IDS_PREFIX + geometry.pageNumber))
|
||||
try { editor.sendToBack(ids as any) } catch { /* tldraw 3 keeps creation order behind later region shapes */ }
|
||||
// z-order is enforced by the caller via bringDomainShapesToFront
|
||||
}
|
||||
|
||||
function seedGuide(editor: Editor) {
|
||||
@ -170,7 +174,7 @@ const ExamTemplateSetupInner: React.FC = () => {
|
||||
const shapeId = createShapeId(PDF_PAGE_IDS_PREFIX + newPage.pageNumber)
|
||||
if (!ed.getCurrentPageShapes().find((s) => s.id === shapeId)) {
|
||||
ed.createShapes([{ id: shapeId, type: PDF_PAGE_SHAPE_TYPE, x: geometry.x, y: geometry.y, isLocked: true, props: { w: geometry.w, h: geometry.h, src: newPage.src, pageNumber: newPage.pageNumber } } as any])
|
||||
try { ed.sendToBack([shapeId as any]) } catch { /* */ }
|
||||
bringDomainShapesToFront(ed)
|
||||
}
|
||||
}
|
||||
setPdfStatus('ready')
|
||||
@ -188,6 +192,7 @@ const ExamTemplateSetupInner: React.FC = () => {
|
||||
if (editor) {
|
||||
syncPdfPages(editor, pages)
|
||||
loadShapes(editor, shapesFromTemplate(detail, geometries))
|
||||
bringDomainShapesToFront(editor)
|
||||
}
|
||||
setDirty(false)
|
||||
} catch (e) {
|
||||
@ -256,6 +261,7 @@ const ExamTemplateSetupInner: React.FC = () => {
|
||||
editor.user.updateUserPreferences({ colorScheme: theme.palette.mode === 'dark' ? 'dark' : 'light' })
|
||||
editor.store.listen(() => setDirty(true), { scope: 'document' })
|
||||
if (template) loadShapes(editor, shapesFromTemplate(template, pageGeometriesRef.current)); else seedGuide(editor)
|
||||
bringDomainShapesToFront(editor)
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user