From 53e5726d3629a08f1c673c95460bd6d721af92e3 Mon Sep 17 00:00:00 2001 From: Yifeng Wang Date: Tue, 11 Feb 2025 14:16:17 +0800 Subject: [PATCH] refactor(editor): move worker renderer to affine shared (#10081) --- blocksuite/affine/shared/package.json | 1 + .../shared/src/viewport-renderer/index.ts | 2 ++ .../src/viewport-renderer}/painter.worker.ts | 0 .../src/viewport-renderer}/text-utils.ts | 2 +- .../shared/src/viewport-renderer}/types.ts | 10 +++--- .../viewport-renderer/viewport-renderer.ts} | 33 ++++++++----------- .../playground/examples/renderer/main.ts | 21 ++++++++---- 7 files changed, 37 insertions(+), 32 deletions(-) create mode 100644 blocksuite/affine/shared/src/viewport-renderer/index.ts rename blocksuite/{playground/examples/renderer => affine/shared/src/viewport-renderer}/painter.worker.ts (100%) rename blocksuite/{playground/examples/renderer => affine/shared/src/viewport-renderer}/text-utils.ts (98%) rename blocksuite/{playground/examples/renderer => affine/shared/src/viewport-renderer}/types.ts (100%) rename blocksuite/{playground/examples/renderer/canvas-renderer.ts => affine/shared/src/viewport-renderer/viewport-renderer.ts} (89%) diff --git a/blocksuite/affine/shared/package.json b/blocksuite/affine/shared/package.json index 7de55d5d13..684d610d50 100644 --- a/blocksuite/affine/shared/package.json +++ b/blocksuite/affine/shared/package.json @@ -61,6 +61,7 @@ "./theme": "./src/theme/index.ts", "./styles": "./src/styles/index.ts", "./services": "./src/services/index.ts", + "./viewport-renderer": "./src/viewport-renderer/index.ts", "./adapters": "./src/adapters/index.ts" }, "files": [ diff --git a/blocksuite/affine/shared/src/viewport-renderer/index.ts b/blocksuite/affine/shared/src/viewport-renderer/index.ts new file mode 100644 index 0000000000..00cdc723e3 --- /dev/null +++ b/blocksuite/affine/shared/src/viewport-renderer/index.ts @@ -0,0 +1,2 @@ +export * from './types.js'; +export * from './viewport-renderer.js'; diff --git a/blocksuite/playground/examples/renderer/painter.worker.ts b/blocksuite/affine/shared/src/viewport-renderer/painter.worker.ts similarity index 100% rename from blocksuite/playground/examples/renderer/painter.worker.ts rename to blocksuite/affine/shared/src/viewport-renderer/painter.worker.ts diff --git a/blocksuite/playground/examples/renderer/text-utils.ts b/blocksuite/affine/shared/src/viewport-renderer/text-utils.ts similarity index 98% rename from blocksuite/playground/examples/renderer/text-utils.ts rename to blocksuite/affine/shared/src/viewport-renderer/text-utils.ts index 7f229254a3..d4bd25dde2 100644 --- a/blocksuite/playground/examples/renderer/text-utils.ts +++ b/blocksuite/affine/shared/src/viewport-renderer/text-utils.ts @@ -1,4 +1,4 @@ -import type { TextRect } from './types'; +import type { TextRect } from './types.js'; interface WordSegment { text: string; diff --git a/blocksuite/playground/examples/renderer/types.ts b/blocksuite/affine/shared/src/viewport-renderer/types.ts similarity index 100% rename from blocksuite/playground/examples/renderer/types.ts rename to blocksuite/affine/shared/src/viewport-renderer/types.ts index 6af1f8c5fd..8483555a56 100644 --- a/blocksuite/playground/examples/renderer/types.ts +++ b/blocksuite/affine/shared/src/viewport-renderer/types.ts @@ -23,12 +23,12 @@ export interface ParagraphLayout { zoom: number; } -export interface TextRect { - rect: Rect; - text: string; -} - export interface SectionLayout { paragraphs: ParagraphLayout[]; rect: Rect; } + +export interface TextRect { + rect: Rect; + text: string; +} diff --git a/blocksuite/playground/examples/renderer/canvas-renderer.ts b/blocksuite/affine/shared/src/viewport-renderer/viewport-renderer.ts similarity index 89% rename from blocksuite/playground/examples/renderer/canvas-renderer.ts rename to blocksuite/affine/shared/src/viewport-renderer/viewport-renderer.ts index 7a0605b14e..20fb3ecf0c 100644 --- a/blocksuite/playground/examples/renderer/canvas-renderer.ts +++ b/blocksuite/affine/shared/src/viewport-renderer/viewport-renderer.ts @@ -1,24 +1,19 @@ +import type { EditorHost } from '@blocksuite/block-std'; import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx'; -import type { AffineEditorContainer } from '@blocksuite/presets'; import { getSentenceRects, segmentSentences } from './text-utils.js'; import { type ParagraphLayout, type SectionLayout } from './types.js'; -export class CanvasRenderer { - private readonly worker: Worker; - private readonly editorContainer: AffineEditorContainer; - private readonly targetContainer: HTMLElement; +export class ViewportTurboRenderer { public readonly canvas: HTMLCanvasElement = document.createElement('canvas'); + private readonly worker: Worker; + private readonly targetContainer: HTMLElement; + private host!: EditorHost; private lastZoom: number | null = null; private lastSection: SectionLayout | null = null; private lastBitmap: ImageBitmap | null = null; - private lastMode: 'page' | 'edgeless' = 'edgeless'; - constructor( - editorContainer: AffineEditorContainer, - targetContainer: HTMLElement - ) { - this.editorContainer = editorContainer; + constructor(targetContainer: HTMLElement) { this.targetContainer = targetContainer; this.worker = new Worker(new URL('./painter.worker.ts', import.meta.url), { @@ -30,16 +25,20 @@ export class CanvasRenderer { } } + setHost(host: EditorHost) { + this.host = host; + } + get viewport() { - return this.editorContainer.std.get(GfxControllerIdentifier).viewport; + return this.host.std.get(GfxControllerIdentifier).viewport; } getHostRect() { - return this.editorContainer.host!.getBoundingClientRect(); + return this.host.getBoundingClientRect(); } getHostLayout() { - const paragraphBlocks = this.editorContainer.host!.querySelectorAll( + const paragraphBlocks = this.host.querySelectorAll( '.affine-paragraph-rich-text-wrapper [data-v-text="true"]' ); @@ -161,7 +160,6 @@ export class CanvasRenderer { private updateCacheState(section: SectionLayout, bitmapCopy: ImageBitmap) { this.lastZoom = this.viewport.zoom; this.lastSection = section; - this.lastMode = this.editorContainer.mode; if (this.lastBitmap) { this.lastBitmap.close(); } @@ -170,10 +168,7 @@ export class CanvasRenderer { private canUseCache(currentZoom: number): boolean { return ( - this.lastZoom === currentZoom && - !!this.lastSection && - !!this.lastBitmap && - this.lastMode === this.editorContainer.mode + this.lastZoom === currentZoom && !!this.lastSection && !!this.lastBitmap ); } diff --git a/blocksuite/playground/examples/renderer/main.ts b/blocksuite/playground/examples/renderer/main.ts index a20f386d60..7fe678fbfa 100644 --- a/blocksuite/playground/examples/renderer/main.ts +++ b/blocksuite/playground/examples/renderer/main.ts @@ -1,16 +1,18 @@ +import { ViewportTurboRenderer } from '@blocksuite/affine-shared/viewport-renderer'; import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx'; +import { nextTick } from '@blocksuite/global/utils'; import { Text } from '@blocksuite/store'; import { Pane } from 'tweakpane'; -import { CanvasRenderer } from './canvas-renderer.js'; import { doc, editor } from './editor.js'; type DocMode = 'page' | 'edgeless'; -const container = document.querySelector('#right-column') as HTMLElement; -const renderer = new CanvasRenderer(editor, container); +const rightColumn = document.querySelector('#right-column') as HTMLElement; +const renderer = new ViewportTurboRenderer(rightColumn); async function handleToCanvasClick() { + renderer.setHost(editor.host!); await renderer.render(); const viewport = editor.std.get(GfxControllerIdentifier).viewport; viewport.viewportUpdated.on(async () => { @@ -18,6 +20,13 @@ async function handleToCanvasClick() { }); } +async function handleModeChange(mode: DocMode) { + editor.mode = mode; + await nextTick(); + renderer.setHost(editor.host!); + await renderer.render(); +} + function initUI() { const pane = new Pane({ container: document.querySelector('#tweakpane-container') as HTMLElement, @@ -34,7 +43,6 @@ function initUI() { .on('click', () => { handleToCanvasClick().catch(console.error); }); - pane .addBinding(params, 'mode', { label: 'Editor Mode', @@ -44,10 +52,8 @@ function initUI() { }, }) .on('change', ({ value }) => { - editor.mode = value as DocMode; + handleModeChange(value as DocMode).catch(console.error); }); - - document.querySelector('#left-column')?.append(editor); } function addParagraph(content: string) { @@ -61,6 +67,7 @@ function addParagraph(content: string) { function main() { initUI(); + document.querySelector('#left-column')?.append(editor); const firstParagraph = doc.getBlockByFlavour('affine:paragraph')[0]; doc.updateBlock(firstParagraph, { text: new Text('Renderer') });