mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 01:09:54 +08:00
refactor(editor): separate the element renders (#11461)
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import {
|
||||
ConnectorPathGenerator,
|
||||
type ElementRenderer,
|
||||
ElementRendererExtension,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { connector as renderConnector } from '@blocksuite/affine-gfx-connector';
|
||||
import type {
|
||||
MindmapElementModel,
|
||||
MindmapNode,
|
||||
} from '@blocksuite/affine-model';
|
||||
import type { GfxModel } from '@blocksuite/std/gfx';
|
||||
|
||||
export const mindmap: ElementRenderer<MindmapElementModel> = (
|
||||
model,
|
||||
ctx,
|
||||
matrix,
|
||||
renderer,
|
||||
rc,
|
||||
bound
|
||||
) => {
|
||||
const dx = model.x - bound.x;
|
||||
const dy = model.y - bound.y;
|
||||
|
||||
matrix = matrix.translate(-dx, -dy);
|
||||
|
||||
const mindmapOpacity = model.opacity;
|
||||
|
||||
const traverse = (node: MindmapNode) => {
|
||||
const connectors = model.getConnectors(node);
|
||||
if (!connectors) return;
|
||||
connectors.reverse().forEach(result => {
|
||||
const { connector, outdated } = result;
|
||||
const elementGetter = (id: string) =>
|
||||
model.surface.getElementById(id) ??
|
||||
(model.surface.doc.getModelById(id) as GfxModel);
|
||||
|
||||
if (outdated) {
|
||||
ConnectorPathGenerator.updatePath(connector, null, elementGetter);
|
||||
}
|
||||
|
||||
const dx = connector.x - bound.x;
|
||||
const dy = connector.y - bound.y;
|
||||
const origin = ctx.globalAlpha;
|
||||
const shouldSetGlobalAlpha =
|
||||
origin !== connector.opacity * mindmapOpacity;
|
||||
|
||||
if (shouldSetGlobalAlpha) {
|
||||
ctx.globalAlpha = connector.opacity * mindmapOpacity;
|
||||
}
|
||||
|
||||
renderConnector(
|
||||
connector,
|
||||
ctx,
|
||||
matrix.translate(dx, dy),
|
||||
renderer,
|
||||
rc,
|
||||
// NOTE: should we add this?
|
||||
bound
|
||||
);
|
||||
|
||||
if (shouldSetGlobalAlpha) {
|
||||
ctx.globalAlpha = origin;
|
||||
}
|
||||
});
|
||||
|
||||
if (node.detail.collapsed) {
|
||||
return;
|
||||
} else {
|
||||
node.children.forEach(traverse);
|
||||
}
|
||||
};
|
||||
|
||||
model.tree && traverse(model.tree);
|
||||
};
|
||||
|
||||
export const MindmapElementRendererExtension = ElementRendererExtension(
|
||||
'mindmap',
|
||||
mindmap
|
||||
);
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './element-renderer';
|
||||
export * from './element-transform';
|
||||
export * from './indicator-overlay';
|
||||
export * from './toolbar/config';
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { addAttachments } from '@blocksuite/affine-block-attachment';
|
||||
import { insertEdgelessTextCommand } from '@blocksuite/affine-block-edgeless-text';
|
||||
import { addImages } from '@blocksuite/affine-block-image';
|
||||
import {
|
||||
CanvasElementType,
|
||||
EdgelessCRUDIdentifier,
|
||||
} from '@blocksuite/affine-block-surface';
|
||||
import { mountTextElementEditor } from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
insertEdgelessTextCommand,
|
||||
mountTextElementEditor,
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import {
|
||||
MAX_IMAGE_WIDTH,
|
||||
type MindmapStyle,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { hasGrouped } from '@blocksuite/affine-gfx-shape';
|
||||
import {
|
||||
LayoutType,
|
||||
MindmapElementModel,
|
||||
MindmapStyle,
|
||||
ShapeElementModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import {
|
||||
type ToolbarContext,
|
||||
@@ -130,7 +132,68 @@ export const mindmapToolbarConfig = {
|
||||
when: ctx => ctx.getSurfaceModelsByType(MindmapElementModel).length > 0,
|
||||
} as const satisfies ToolbarModuleConfig;
|
||||
|
||||
export const shapeMindmapToolbarConfig = {
|
||||
actions: [
|
||||
{
|
||||
id: 'a.mindmap-style',
|
||||
when(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
return models.some(hasGrouped);
|
||||
},
|
||||
content(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
if (!models.length) return null;
|
||||
|
||||
let mindmaps = models
|
||||
.map(model => model.group)
|
||||
.filter(model => ctx.matchModel(model, MindmapElementModel));
|
||||
if (!mindmaps.length) return null;
|
||||
|
||||
// Not displayed when there is both a normal shape and a mindmap shape.
|
||||
if (models.length !== mindmaps.length) return null;
|
||||
|
||||
mindmaps = Array.from(new Set(mindmaps));
|
||||
|
||||
return createMindmapStyleActionMenu(ctx, mindmaps);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'b.mindmap-layout',
|
||||
when(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
return models.some(hasGrouped);
|
||||
},
|
||||
content(ctx) {
|
||||
const models = ctx.getSurfaceModelsByType(ShapeElementModel);
|
||||
if (!models.length) return null;
|
||||
|
||||
let mindmaps = models
|
||||
.map(model => model.group)
|
||||
.filter(model => ctx.matchModel(model, MindmapElementModel));
|
||||
if (!mindmaps.length) return null;
|
||||
|
||||
// Not displayed when there is both a normal shape and a mindmap shape.
|
||||
if (models.length !== mindmaps.length) return null;
|
||||
|
||||
mindmaps = Array.from(new Set(mindmaps));
|
||||
|
||||
// It's a sub node.
|
||||
if (models.length === 1 && mindmaps[0].tree.element !== models[0])
|
||||
return null;
|
||||
|
||||
return createMindmapLayoutActionMenu(ctx, mindmaps);
|
||||
},
|
||||
},
|
||||
],
|
||||
when: ctx => ctx.getSurfaceModelsByType(ShapeElementModel).length > 0,
|
||||
} as const satisfies ToolbarModuleConfig;
|
||||
|
||||
export const mindmapToolbarExtension = ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:mindmap'),
|
||||
config: mindmapToolbarConfig,
|
||||
});
|
||||
|
||||
export const shapeMindmapToolbarExtension = ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('custom:affine:surface:shape'),
|
||||
config: shapeMindmapToolbarConfig,
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { fitContent } from '@blocksuite/affine-block-surface';
|
||||
import { fitContent } from '@blocksuite/affine-gfx-shape';
|
||||
import {
|
||||
applyNodeStyle,
|
||||
LayoutType,
|
||||
|
||||
Reference in New Issue
Block a user