jjb-lc-designable
Version:
基于alibaba-designable源码二次封装的表单设计器。
67 lines (65 loc) • 2.14 kB
text/typescript
import { DragStopEvent } from '../events'
import { Engine, CursorType, TreeNode, CursorDragType } from '../models'
import {
calcRectByStartEndPoint,
isCrossRectInRect,
isRectInRect,
Point,
} from 'jjb-lc-designable/shared'
export const useFreeSelectionEffect = (engine: Engine) => {
engine.subscribeTo(DragStopEvent, (event) => {
if (engine.cursor.dragType !== CursorDragType.Move) {
return
}
engine.workbench.eachWorkspace((workspace) => {
const viewport = workspace.viewport
const dragEndPoint = new Point(
event.data.topClientX,
event.data.topClientY
)
const dragStartOffsetPoint = viewport.getOffsetPoint(
new Point(
engine.cursor.dragStartPosition.topClientX,
engine.cursor.dragStartPosition.topClientY
)
)
const dragEndOffsetPoint = viewport.getOffsetPoint(
new Point(
engine.cursor.position.topClientX,
engine.cursor.position.topClientY
)
)
if (!viewport.isPointInViewport(dragEndPoint, false)) return
const tree = workspace.operation.tree
const selectionRect = calcRectByStartEndPoint(
dragStartOffsetPoint,
dragEndOffsetPoint,
viewport.dragScrollXDelta,
viewport.dragScrollYDelta
)
const selected: [TreeNode, DOMRect][] = []
tree.eachChildren((node) => {
const nodeRect = viewport.getValidNodeOffsetRect(node)
if (nodeRect && isCrossRectInRect(selectionRect, nodeRect)) {
// @ts-ignore
selected.push([node, nodeRect])
}
})
const selectedNodes: TreeNode[] = selected.reduce(
(buf, [node, nodeRect]) => {
if (isRectInRect(nodeRect, selectionRect)) {
if (selected.some(([selectNode]) => selectNode.isMyParents(node))) {
return buf
}
}
return buf.concat(node)
},
[]
)
workspace.operation.selection.batchSafeSelect(selectedNodes)
})
if (engine.cursor.type === CursorType.Selection) {
engine.cursor.setType(CursorType.Normal)
}
})
}