diff --git a/src/canvas/fabric-canvas.tsx b/src/canvas/fabric-canvas.tsx index 39a31cfb1..46b2a9cdc 100644 --- a/src/canvas/fabric-canvas.tsx +++ b/src/canvas/fabric-canvas.tsx @@ -6,6 +6,7 @@ import { useCanvasViewport } from './use-canvas-viewport' import { useCanvasSelection } from './use-canvas-selection' import { useCanvasSync } from './use-canvas-sync' import { useDimensionLabel } from './use-dimension-label' +import { useFrameLabels } from './use-frame-labels' export default function FabricCanvas() { const canvasRef = useRef(null) @@ -18,6 +19,7 @@ export default function FabricCanvas() { useCanvasSelection() useCanvasSync() useDimensionLabel(containerRef) + useFrameLabels() return (
{ + const interval = setInterval(() => { + const canvas = useCanvasStore.getState().fabricCanvas + if (!canvas) return + clearInterval(interval) + + const onAfterRender = () => { + const el = canvas.lowerCanvasEl + if (!el) return + const ctx = el.getContext('2d') + if (!ctx) return + + const vpt = canvas.viewportTransform + if (!vpt) return + const zoom = vpt[0] + const dpr = el.width / el.offsetWidth + + const store = useDocumentStore.getState() + // Only top-level document children show labels + const topIds = new Set(store.document.children.map((c) => c.id)) + const objects = canvas.getObjects() as FabricObjectWithPenId[] + + ctx.save() + const fontSize = LABEL_FONT_SIZE * dpr + ctx.font = `500 ${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif` + ctx.fillStyle = LABEL_COLOR + + for (const obj of objects) { + if (!obj.penNodeId) continue + if (!topIds.has(obj.penNodeId)) continue + + const node = store.getNodeById(obj.penNodeId) + if (!node) continue + + const name = node.name ?? node.type + const x = ((obj.left ?? 0) * zoom + vpt[4]) * dpr + const y = ((obj.top ?? 0) * zoom + vpt[5]) * dpr + + ctx.fillText(name, x, y - LABEL_OFFSET_Y * dpr) + } + + ctx.restore() + } + + canvas.on('after:render', onAfterRender) + + return () => { + canvas.off('after:render', onAfterRender) + } + }, 100) + + return () => clearInterval(interval) + }, []) +}