mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-22 20:41:50 +08:00
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 -->
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import {
|
||||
getFontString,
|
||||
getLineHeight,
|
||||
getLineWidth,
|
||||
truncateTextByWidth,
|
||||
} from '@blocksuite/affine-gfx-text';
|
||||
import type { GroupElementModel } from '@blocksuite/affine-model';
|
||||
import { FontWeight } from '@blocksuite/affine-model';
|
||||
import { Bound } from '@blocksuite/global/gfx';
|
||||
|
||||
import {
|
||||
GROUP_TITLE_FONT,
|
||||
GROUP_TITLE_FONT_SIZE,
|
||||
GROUP_TITLE_OFFSET,
|
||||
GROUP_TITLE_PADDING,
|
||||
} from './consts';
|
||||
|
||||
export function titleRenderParams(group: GroupElementModel, zoom: number) {
|
||||
let text = group.title.toString().trim();
|
||||
const font = getGroupTitleFont(zoom);
|
||||
const lineWidth = getLineWidth(text, font);
|
||||
const lineHeight = getLineHeight(
|
||||
GROUP_TITLE_FONT,
|
||||
GROUP_TITLE_FONT_SIZE / zoom,
|
||||
'normal'
|
||||
);
|
||||
const bound = group.elementBound;
|
||||
const padding = [
|
||||
GROUP_TITLE_PADDING[0] / zoom,
|
||||
GROUP_TITLE_PADDING[1] / zoom,
|
||||
];
|
||||
const offset = GROUP_TITLE_OFFSET / zoom;
|
||||
|
||||
let titleWidth = lineWidth + padding[0] * 2;
|
||||
const titleHeight = lineHeight + padding[1] * 2;
|
||||
|
||||
if (titleWidth > bound.w) {
|
||||
text = truncateTextByWidth(text, font, bound.w - 10);
|
||||
text = text.slice(0, text.length - 1) + '..';
|
||||
titleWidth = bound.w;
|
||||
}
|
||||
|
||||
return {
|
||||
font,
|
||||
bound,
|
||||
text,
|
||||
titleWidth,
|
||||
titleHeight,
|
||||
offset,
|
||||
lineHeight,
|
||||
padding,
|
||||
titleBound: new Bound(
|
||||
bound.x,
|
||||
bound.y - titleHeight - offset,
|
||||
titleWidth,
|
||||
titleHeight
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
export function titleBound(group: GroupElementModel, zoom: number) {
|
||||
const { titleWidth, titleHeight, bound } = titleRenderParams(group, zoom);
|
||||
|
||||
return new Bound(bound.x, bound.y - titleHeight, titleWidth, titleHeight);
|
||||
}
|
||||
|
||||
function getGroupTitleFont(zoom: number) {
|
||||
const fontSize = GROUP_TITLE_FONT_SIZE / zoom;
|
||||
const font = getFontString({
|
||||
fontSize,
|
||||
fontFamily: GROUP_TITLE_FONT,
|
||||
fontWeight: FontWeight.Regular,
|
||||
fontStyle: 'normal',
|
||||
});
|
||||
|
||||
return font;
|
||||
}
|
||||
Reference in New Issue
Block a user