Files
AFFiNE-Mirror/blocksuite/affine/gfx/mindmap/src/renderer/element-renderer.ts
T
L-Sun 680f3b3006 feat(editor): impl shape text with dom renderer (#13471)
#### PR Dependency Tree


* **PR #13464**
  * **PR #13465**
    * **PR #13471** 👈
      * **PR #13472**
        * **PR #13473**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* DOM rendering added for groups, mind maps and connectors so group
titles/outlines and mindmap connectors are visible on canvas.
* Shapes now support right-to-left text with proper vertical alignment.
* **Improvements**
  * Connector labels scale with viewport zoom for crisper display.
* Group-related selections (including nested groups) now update visuals
consistently.
* **Performance**
* Reduced DOM churn and fewer redraws during rendering and selection
changes.
* **Refactor**
* Renderer import/export surfaces consolidated with no user-facing
behavior changes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-08-14 04:29:13 +00:00

82 lines
1.9 KiB
TypeScript

import {
type ElementRenderer,
ElementRendererExtension,
} from '@blocksuite/affine-block-surface';
import {
connector as renderConnector,
ConnectorPathGenerator,
} 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.store.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
);