From 34039bc7d87e5c15cb570c8013811befe7e13a0d Mon Sep 17 00:00:00 2001 From: doodlewind <7312949+doodlewind@users.noreply.github.com> Date: Tue, 29 Apr 2025 08:18:57 +0000 Subject: [PATCH] refactor(editor): use default fallback placeholder for turbo renderer (#12059) Based on this PR, all block types support zooming placeholder now. ![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/lEGcysB4lFTEbCwZ8jMv/33a32735-d31e-4055-9dbf-faaed444a6d2.png) ## Summary by CodeRabbit - **Improvements** - Enhanced layout rendering accuracy for non-root nodes, leading to more precise placement and sizing. - Simplified placeholder painting logic for improved consistency, with all nodes now displayed using a color based on their depth. --- .../gfx/turbo-renderer/src/renderer-utils.ts | 59 ++++++++++++------- .../gfx/turbo-renderer/src/turbo-renderer.ts | 7 +-- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/blocksuite/affine/gfx/turbo-renderer/src/renderer-utils.ts b/blocksuite/affine/gfx/turbo-renderer/src/renderer-utils.ts index 40a8d37ee7..dbd7f39c12 100644 --- a/blocksuite/affine/gfx/turbo-renderer/src/renderer-utils.ts +++ b/blocksuite/affine/gfx/turbo-renderer/src/renderer-utils.ts @@ -47,7 +47,8 @@ export function getViewportLayoutTree( // Recursive function to build the tree structure const buildLayoutTreeNode = ( model: BlockModel, - ancestorViewportState?: string | null + ancestorViewportState?: string | null, + root = false ): BlockLayoutTreeNode | null => { const baseLayout: BlockLayout = { blockId: model.id, @@ -92,6 +93,29 @@ export function getViewportLayoutTree( layoutMinY = Math.min(layoutMinY, calculatedRect.y); layoutMaxX = Math.max(layoutMaxX, calculatedRect.x + calculatedRect.w); layoutMaxY = Math.max(layoutMaxY, calculatedRect.y + calculatedRect.h); + } else if (component && !root) { + const clientRect = component.getBoundingClientRect(); + const [modelX, modelY] = viewport.toModelCoordFromClientCoord([ + clientRect.x, + clientRect.y, + ]); + + const rect = { + x: modelX, + y: modelY, + w: clientRect.width / zoom / viewport.viewScale, + h: clientRect.height / zoom / viewport.viewScale, + }; + + layout = { + ...baseLayout, + rect, + }; + + layoutMinX = Math.min(layoutMinX, rect.x); + layoutMinY = Math.min(layoutMinY, rect.y); + layoutMaxX = Math.max(layoutMaxX, rect.x + rect.w); + layoutMaxY = Math.max(layoutMaxY, rect.y + rect.h); } else { layoutMinX = Math.min(layoutMinX, baseLayout.rect.x); layoutMinY = Math.min(layoutMinY, baseLayout.rect.y); @@ -116,7 +140,7 @@ export function getViewportLayoutTree( }; const roots: BlockLayoutTreeNode[] = []; - const rootNode = buildLayoutTreeNode(rootModel); + const rootNode = buildLayoutTreeNode(rootModel, null, true); if (rootNode) { roots.push(rootNode); } @@ -155,7 +179,6 @@ export function debugLog(message: string, state: RenderingState) { } export function paintPlaceholder( - host: EditorHost, canvas: HTMLCanvasElement, layout: ViewportLayoutTree | null, viewport: Viewport @@ -175,27 +198,19 @@ export function paintPlaceholder( 'rgba(160, 160, 160, 0.7)', ]; - const layoutHandlers = host.std.provider.getAll( - BlockLayoutHandlersIdentifier - ); - const handlersArray = Array.from(layoutHandlers.values()); - const paintNode = (node: BlockLayoutTreeNode, depth: number = 0) => { - const { layout: nodeLayout, type } = node; - const handler = handlersArray.find(h => h.blockType === type); - if (handler) { - ctx.fillStyle = colors[depth % colors.length]; - const rect = nodeLayout.rect; - const x = ((rect.x - overallRect.x) * viewport.zoom + offsetX) * dpr; - const y = ((rect.y - overallRect.y) * viewport.zoom + offsetY) * dpr; - const width = rect.w * viewport.zoom * dpr; - const height = rect.h * viewport.zoom * dpr; + const { layout: nodeLayout } = node; + ctx.fillStyle = colors[depth % colors.length]; + const rect = nodeLayout.rect; + const x = ((rect.x - overallRect.x) * viewport.zoom + offsetX) * dpr; + const y = ((rect.y - overallRect.y) * viewport.zoom + offsetY) * dpr; + const width = rect.w * viewport.zoom * dpr; + const height = rect.h * viewport.zoom * dpr; - ctx.fillRect(x, y, width, height); - if (width > 10 && height > 5) { - ctx.strokeStyle = 'rgba(150, 150, 150, 0.3)'; - ctx.strokeRect(x, y, width, height); - } + ctx.fillRect(x, y, width, height); + if (width > 10 && height > 5) { + ctx.strokeStyle = 'rgba(150, 150, 150, 0.3)'; + ctx.strokeRect(x, y, width, height); } if (node.children.length > 0) { diff --git a/blocksuite/affine/gfx/turbo-renderer/src/turbo-renderer.ts b/blocksuite/affine/gfx/turbo-renderer/src/turbo-renderer.ts index d71155c4f3..fcba97786c 100644 --- a/blocksuite/affine/gfx/turbo-renderer/src/turbo-renderer.ts +++ b/blocksuite/affine/gfx/turbo-renderer/src/turbo-renderer.ts @@ -422,12 +422,7 @@ export class ViewportTurboRendererExtension extends GfxExtension { } private paintPlaceholder() { - paintPlaceholder( - this.std.host, - this.canvas, - this.layoutCache, - this.viewport - ); + paintPlaceholder(this.canvas, this.layoutCache, this.viewport); } }