refactor(editor): move worker renderer to affine shared (#10081)

This commit is contained in:
Yifeng Wang
2025-02-11 14:16:17 +08:00
committed by GitHub
parent d89d4a71dd
commit 53e5726d36
7 changed files with 37 additions and 32 deletions
+1
View File
@@ -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": [
@@ -0,0 +1,2 @@
export * from './types.js';
export * from './viewport-renderer.js';
@@ -1,4 +1,4 @@
import type { TextRect } from './types';
import type { TextRect } from './types.js';
interface WordSegment {
text: string;
@@ -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;
}
@@ -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
);
}
@@ -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') });