mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-17 14:27:02 +08:00
feat(editor): block painter extension (#10847)
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import type {
|
||||
BlockLayout,
|
||||
BlockLayoutPainter,
|
||||
TextRect,
|
||||
WorkerToHostMessage,
|
||||
import {
|
||||
type BlockLayout,
|
||||
type BlockLayoutPainter,
|
||||
BlockLayoutPainterExtension,
|
||||
type TextRect,
|
||||
type WorkerToHostMessage,
|
||||
} from '@blocksuite/affine-gfx-turbo-renderer';
|
||||
|
||||
interface SentenceLayout {
|
||||
@@ -39,7 +40,7 @@ function isParagraphLayout(layout: BlockLayout): layout is ParagraphLayout {
|
||||
return layout.type === 'affine:paragraph';
|
||||
}
|
||||
|
||||
export class ParagraphLayoutPainter implements BlockLayoutPainter {
|
||||
class ParagraphLayoutPainter implements BlockLayoutPainter {
|
||||
private static readonly supportFontFace =
|
||||
typeof FontFace !== 'undefined' &&
|
||||
typeof self !== 'undefined' &&
|
||||
@@ -114,3 +115,8 @@ export class ParagraphLayoutPainter implements BlockLayoutPainter {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const ParagraphLayoutPainterExtension = BlockLayoutPainterExtension(
|
||||
'affine:paragraph',
|
||||
ParagraphLayoutPainter
|
||||
);
|
||||
|
||||
19
blocksuite/affine/gfx/turbo-renderer/src/extension/index.ts
Normal file
19
blocksuite/affine/gfx/turbo-renderer/src/extension/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { createIdentifier } from '@blocksuite/global/di';
|
||||
import type { ExtensionType } from '@blocksuite/store';
|
||||
|
||||
import type { BlockLayoutPainter } from '../types';
|
||||
|
||||
export const BlockPainterProvider = createIdentifier<BlockLayoutPainter>(
|
||||
'block-painter-provider'
|
||||
);
|
||||
|
||||
export const BlockLayoutPainterExtension = (
|
||||
type: string,
|
||||
painter: new () => BlockLayoutPainter
|
||||
): ExtensionType => {
|
||||
return {
|
||||
setup: di => {
|
||||
di.addImpl(BlockPainterProvider(type), painter);
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './extension';
|
||||
export * from './layout/block-layout-provider';
|
||||
export * from './painter/painter.worker';
|
||||
export * from './text-utils';
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import { Container, type ServiceProvider } from '@blocksuite/global/di';
|
||||
import type { ExtensionType } from '@blocksuite/store';
|
||||
|
||||
import { BlockPainterProvider } from '../extension';
|
||||
import type {
|
||||
BlockLayoutPainter,
|
||||
HostToWorkerMessage,
|
||||
@@ -5,28 +9,25 @@ import type {
|
||||
WorkerToHostMessage,
|
||||
} from '../types';
|
||||
|
||||
class BlockPainterRegistry {
|
||||
private readonly painters = new Map<string, BlockLayoutPainter>();
|
||||
|
||||
register(type: string, painter: BlockLayoutPainter) {
|
||||
this.painters.set(type, painter);
|
||||
}
|
||||
|
||||
getPainter(type: string): BlockLayoutPainter | undefined {
|
||||
return this.painters.get(type);
|
||||
}
|
||||
}
|
||||
|
||||
export class ViewportLayoutPainter {
|
||||
private readonly canvas: OffscreenCanvas = new OffscreenCanvas(0, 0);
|
||||
private ctx: OffscreenCanvasRenderingContext2D | null = null;
|
||||
private zoom = 1;
|
||||
public readonly registry = new BlockPainterRegistry();
|
||||
public provider: ServiceProvider;
|
||||
|
||||
constructor(painters: Record<string, BlockLayoutPainter>) {
|
||||
Object.entries(painters).forEach(([type, painter]) => {
|
||||
this.registry.register(type, painter);
|
||||
getPainter(type: string): BlockLayoutPainter | undefined {
|
||||
return this.provider.get(BlockPainterProvider(type));
|
||||
}
|
||||
|
||||
constructor(extensions: ExtensionType[]) {
|
||||
const container = new Container();
|
||||
|
||||
extensions.forEach(extension => {
|
||||
extension.setup(container);
|
||||
});
|
||||
|
||||
this.provider = container.provider();
|
||||
|
||||
self.onmessage = this.handler;
|
||||
}
|
||||
|
||||
@@ -60,7 +61,7 @@ export class ViewportLayoutPainter {
|
||||
ctx.scale(this.zoom, this.zoom);
|
||||
|
||||
layout.blocks.forEach(blockLayout => {
|
||||
const painter = this.registry.getPainter(blockLayout.type);
|
||||
const painter = this.getPainter(blockLayout.type);
|
||||
if (!painter) return;
|
||||
painter.paint(ctx, blockLayout, layout.rect.x, layout.rect.y);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { ParagraphLayoutPainter } from '@blocksuite/affine-block-paragraph/turbo-painter';
|
||||
import { ParagraphLayoutPainterExtension } from '@blocksuite/affine-block-paragraph/turbo-painter';
|
||||
import { ViewportLayoutPainter } from '@blocksuite/affine-gfx-turbo-renderer/painter';
|
||||
|
||||
new ViewportLayoutPainter({
|
||||
'affine:paragraph': new ParagraphLayoutPainter(),
|
||||
});
|
||||
new ViewportLayoutPainter([ParagraphLayoutPainterExtension]);
|
||||
|
||||
Reference in New Issue
Block a user