mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
refactor(editor): query methods in edgeless api (#9407)
This commit is contained in:
79
blocksuite/affine/shared/src/utils/edgeless.ts
Normal file
79
blocksuite/affine/shared/src/utils/edgeless.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { FrameBlockModel, GroupElementModel } from '@blocksuite/affine-model';
|
||||
import type { GfxBlockElementModel } from '@blocksuite/block-std/gfx';
|
||||
import {
|
||||
deserializeXYWH,
|
||||
getQuadBoundWithRotation,
|
||||
} from '@blocksuite/global/utils';
|
||||
import type { BlockModel } from '@blocksuite/store';
|
||||
|
||||
export function getSelectedRect(selected: BlockSuite.EdgelessModel[]): DOMRect {
|
||||
if (selected.length === 0) {
|
||||
return new DOMRect();
|
||||
}
|
||||
|
||||
const lockedElementsByFrame = selected
|
||||
.map(selectable => {
|
||||
if (selectable instanceof FrameBlockModel && selectable.isLocked()) {
|
||||
return selectable.descendantElements;
|
||||
}
|
||||
return [];
|
||||
})
|
||||
.flat();
|
||||
|
||||
selected = [...new Set([...selected, ...lockedElementsByFrame])];
|
||||
|
||||
if (selected.length === 1) {
|
||||
const [x, y, w, h] = deserializeXYWH(selected[0].xywh);
|
||||
return new DOMRect(x, y, w, h);
|
||||
}
|
||||
|
||||
return getElementsWithoutGroup(selected).reduce(
|
||||
(bounds, selectable, index) => {
|
||||
const rotate = isTopLevelBlock(selectable) ? 0 : selectable.rotate;
|
||||
const [x, y, w, h] = deserializeXYWH(selectable.xywh);
|
||||
let { left, top, right, bottom } = getQuadBoundWithRotation({
|
||||
x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
rotate,
|
||||
});
|
||||
|
||||
if (index !== 0) {
|
||||
left = Math.min(left, bounds.left);
|
||||
top = Math.min(top, bounds.top);
|
||||
right = Math.max(right, bounds.right);
|
||||
bottom = Math.max(bottom, bounds.bottom);
|
||||
}
|
||||
|
||||
bounds.x = left;
|
||||
bounds.y = top;
|
||||
bounds.width = right - left;
|
||||
bounds.height = bottom - top;
|
||||
|
||||
return bounds;
|
||||
},
|
||||
new DOMRect()
|
||||
);
|
||||
}
|
||||
|
||||
export function getElementsWithoutGroup(elements: BlockSuite.EdgelessModel[]) {
|
||||
const set = new Set<BlockSuite.EdgelessModel>();
|
||||
|
||||
elements.forEach(element => {
|
||||
if (element instanceof GroupElementModel) {
|
||||
element.descendantElements
|
||||
.filter(descendant => !(descendant instanceof GroupElementModel))
|
||||
.forEach(descendant => set.add(descendant));
|
||||
} else {
|
||||
set.add(element);
|
||||
}
|
||||
});
|
||||
return Array.from(set);
|
||||
}
|
||||
|
||||
export function isTopLevelBlock(
|
||||
selectable: BlockModel | BlockSuite.EdgelessModel | null
|
||||
): selectable is GfxBlockElementModel {
|
||||
return !!selectable && 'flavour' in selectable;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ export * from './button-popper.js';
|
||||
export * from './collapsed/index.js';
|
||||
export * from './dnd/index.js';
|
||||
export * from './dom/index.js';
|
||||
export * from './edgeless.js';
|
||||
export * from './event.js';
|
||||
export * from './file/index.js';
|
||||
export * from './insert.js';
|
||||
|
||||
Reference in New Issue
Block a user