jjb-lc-designable
Version:
基于alibaba-designable源码二次封装的表单设计器。
144 lines • 6.54 kB
JavaScript
import { ClosestPosition, CursorType, CursorDragType, TreeNode } from '../models';
import { DragStartEvent, DragMoveEvent, DragStopEvent, ViewportScrollEvent } from '../events';
import { Point } from 'jjb-lc-designable/shared';
export const useDragDropEffect = engine => {
engine.subscribeTo(DragStartEvent, event => {
if (engine.cursor.type !== CursorType.Normal) return;
const target = event.data.target;
const el = target?.closest(`
*[${engine.props.nodeIdAttrName}],
*[${engine.props.sourceIdAttrName}],
*[${engine.props.outlineNodeIdAttrName}]
`);
const handler = target?.closest(`*[${engine.props.nodeDragHandlerAttrName}]`);
const helper = handler?.closest(`*[${engine.props.nodeSelectionIdAttrName}]`);
if (!el?.getAttribute && !handler) return;
const sourceId = el?.getAttribute(engine.props.sourceIdAttrName);
const outlineId = el?.getAttribute(engine.props.outlineNodeIdAttrName);
const handlerId = helper?.getAttribute(engine.props.nodeSelectionIdAttrName);
const nodeId = el?.getAttribute(engine.props.nodeIdAttrName);
engine.workbench.eachWorkspace(currentWorkspace => {
const operation = currentWorkspace.operation;
const moveHelper = operation.moveHelper;
if (nodeId || outlineId || handlerId) {
const node = engine.findNodeById(outlineId || nodeId || handlerId);
if (node) {
if (!node.allowDrag()) return;
if (node === node.root) return;
const validSelected = engine.getAllSelectedNodes().filter(node => node.allowDrag());
if (validSelected.some(selectNode => selectNode === node)) {
moveHelper.dragStart({
dragNodes: TreeNode.sort(validSelected)
});
} else {
moveHelper.dragStart({
dragNodes: [node]
});
}
}
} else if (sourceId) {
const sourceNode = engine.findNodeById(sourceId);
if (sourceNode) {
moveHelper.dragStart({
dragNodes: [sourceNode]
});
}
}
});
engine.cursor.setStyle('move');
});
engine.subscribeTo(DragMoveEvent, event => {
if (engine.cursor.type !== CursorType.Normal) return;
if (engine.cursor.dragType !== CursorDragType.Move) return;
const target = event.data.target;
const el = target?.closest(`
*[${engine.props.nodeIdAttrName}],
*[${engine.props.outlineNodeIdAttrName}]
`);
const point = new Point(event.data.topClientX, event.data.topClientY);
const nodeId = el?.getAttribute(engine.props.nodeIdAttrName);
const outlineId = el?.getAttribute(engine.props.outlineNodeIdAttrName);
engine.workbench.eachWorkspace(currentWorkspace => {
const operation = currentWorkspace.operation;
const moveHelper = operation.moveHelper;
const dragNodes = moveHelper.dragNodes;
const tree = operation.tree;
if (!dragNodes.length) return;
const touchNode = tree.findById(outlineId || nodeId);
moveHelper.dragMove({
point,
touchNode
});
});
});
engine.subscribeTo(ViewportScrollEvent, event => {
if (engine.cursor.type !== CursorType.Normal) return;
if (engine.cursor.dragType !== CursorDragType.Move) return;
const point = new Point(engine.cursor.position.topClientX, engine.cursor.position.topClientY);
const currentWorkspace = event?.context?.workspace ?? engine.workbench.activeWorkspace;
if (!currentWorkspace) return;
const operation = currentWorkspace.operation;
const moveHelper = operation.moveHelper;
if (!moveHelper.dragNodes.length) return;
const tree = operation.tree;
const viewport = currentWorkspace.viewport;
const outline = currentWorkspace.outline;
const viewportTarget = viewport.elementFromPoint(point);
const outlineTarget = outline.elementFromPoint(point);
const viewportNodeElement = viewportTarget?.closest(`
*[${engine.props.nodeIdAttrName}],
*[${engine.props.outlineNodeIdAttrName}]
`);
const outlineNodeElement = outlineTarget?.closest(`
*[${engine.props.nodeIdAttrName}],
*[${engine.props.outlineNodeIdAttrName}]
`);
const nodeId = viewportNodeElement?.getAttribute(engine.props.nodeIdAttrName);
const outlineNodeId = outlineNodeElement?.getAttribute(engine.props.outlineNodeIdAttrName);
const touchNode = tree.findById(outlineNodeId || nodeId);
moveHelper.dragMove({
point,
touchNode
});
});
engine.subscribeTo(DragStopEvent, () => {
if (engine.cursor.type !== CursorType.Normal) return;
if (engine.cursor.dragType !== CursorDragType.Move) return;
engine.workbench.eachWorkspace(currentWorkspace => {
const operation = currentWorkspace.operation;
const moveHelper = operation.moveHelper;
const dragNodes = moveHelper.dragNodes;
const closestNode = moveHelper.closestNode;
const closestDirection = moveHelper.closestDirection;
const selection = operation.selection;
if (!dragNodes.length) return;
if (dragNodes.length && closestNode && closestDirection) {
if (closestDirection === ClosestPosition.After || closestDirection === ClosestPosition.Under) {
if (closestNode.allowSibling(dragNodes)) {
selection.batchSafeSelect(closestNode.insertAfter(...TreeNode.filterDroppable(dragNodes, closestNode.parent)));
}
} else if (closestDirection === ClosestPosition.Before || closestDirection === ClosestPosition.Upper) {
if (closestNode.allowSibling(dragNodes)) {
selection.batchSafeSelect(closestNode.insertBefore(...TreeNode.filterDroppable(dragNodes, closestNode.parent)));
}
} else if (closestDirection === ClosestPosition.Inner || closestDirection === ClosestPosition.InnerAfter) {
if (closestNode.allowAppend(dragNodes)) {
selection.batchSafeSelect(closestNode.append(...TreeNode.filterDroppable(dragNodes, closestNode)));
moveHelper.dragDrop({
dropNode: closestNode
});
}
} else if (closestDirection === ClosestPosition.InnerBefore) {
if (closestNode.allowAppend(dragNodes)) {
selection.batchSafeSelect(closestNode.prepend(...TreeNode.filterDroppable(dragNodes, closestNode)));
moveHelper.dragDrop({
dropNode: closestNode
});
}
}
}
moveHelper.dragEnd();
});
engine.cursor.setStyle('');
});
};