Skip to content

Commit

Permalink
perf: 完善对象
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBeard30 committed Mar 13, 2024
1 parent 04bc508 commit 16effa4
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/app/core/drivers/drag-drop-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@ export class DragDropDriver extends EventDriver<Engine> {

onMouseDown = (e: MouseEvent) => {
if (e.button !== 0 || e.ctrlKey || e.metaKey) {
return;
return false;
}
if (e.target['isContentEditable'] || e.target['contentEditable'] === 'true') {
return true;
}
if (e.target?.['closest']?.('.monaco-editor')) return;
if (e.target?.['closest']?.('.monaco-editor')) return false;
GlobalState.startEvent = e;
GlobalState.dragging = false;
GlobalState.onMouseDownAt = Date.now();
this.batchAddEventListener('mouseup', this.onMouseUp);
this.batchAddEventListener('dragend', this.onMouseUp);
this.batchAddEventListener('dragstart', this.onStartDrag);
this.batchAddEventListener('mousemove', this.onDistanceChange);
return;
return false;
};

onMouseUp = (e: MouseEvent) => {
Expand Down
142 changes: 142 additions & 0 deletions src/app/core/effects/useDragDropEffect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { Engine, TreeNode } from '../models';
import { DragMoveEvent, DragStartEvent, DragStopEvent } from '../events/cursor';
import { CursorDragType, CursorType } from '../models/cursor';
import { ClosestPosition } from '../models/move-helper';
import { Point } from '../../shared/coordinate';
import { ViewportScrollEvent } from '../events/viewport';

export const useDragDropEffect = (engine: Engine) => {
engine.subscribeTo(DragStartEvent, event => {
if (engine.cursor.type !== CursorType.Normal) return;
const target = event.data.target as HTMLElement;
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 as HTMLElement;
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('');
});
};
30 changes: 30 additions & 0 deletions src/app/core/events/viewport/AbstractViewportEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { IEngineContext } from '../../types';
import { globalThisPolyfill } from '../../../shared/globalThisPolyfill';

export interface IViewportEventData {
scrollX: number;
scrollY: number;
width: number;
height: number;
view: Window;
innerWidth: number;
innerHeight: number;
target: EventTarget;
}

export class AbstractViewportEvent {
data: IViewportEventData;
context: IEngineContext;
constructor(data: IViewportEventData) {
this.data = data || {
scrollX: globalThisPolyfill.scrollX,
scrollY: globalThisPolyfill.scrollY,
width: globalThisPolyfill.innerWidth,
height: globalThisPolyfill.innerHeight,
innerWidth: globalThisPolyfill.innerWidth,
innerHeight: globalThisPolyfill.innerHeight,
view: globalThisPolyfill,
target: globalThisPolyfill
};
}
}
6 changes: 6 additions & 0 deletions src/app/core/events/viewport/ViewportResizeEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { AbstractViewportEvent } from './AbstractViewportEvent';
import { ICustomEvent } from '../../../shared/event';

export class ViewportResizeEvent extends AbstractViewportEvent implements ICustomEvent {
type = 'viewport:resize';
}
6 changes: 6 additions & 0 deletions src/app/core/events/viewport/ViewportScrollEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ICustomEvent } from '../../../shared/event';
import { AbstractViewportEvent } from './AbstractViewportEvent';

export class ViewportScrollEvent extends AbstractViewportEvent implements ICustomEvent {
type = 'viewport:scroll';
}
2 changes: 2 additions & 0 deletions src/app/core/events/viewport/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './ViewportResizeEvent'
export * from './ViewportScrollEvent'
9 changes: 9 additions & 0 deletions src/app/core/models/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ export class Engine extends Event {
// this.keyboard = new Keyboard(this)
}

getAllSelectedNodes() {
let results: TreeNode[] = [];
for (let i = 0; i < this.workbench.workspaces.length; i++) {
const workspace = this.workbench.workspaces[i];
results = results.concat(workspace.operation.selection.selectedNodes);
}
return results;
}

findNodeById(id: string) {
return TreeNode.findById(id);
}
Expand Down
4 changes: 4 additions & 0 deletions src/app/core/models/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ export class Selection {
operation: Operation;
selected: string[] = [];
indexes: Record<string, boolean> = {};

get selectedNodes() {
return this.selected.map(id => this.operation.tree.findById(id));
}
}
3 changes: 3 additions & 0 deletions src/app/core/presets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { useDragDropEffect } from './effects/useDragDropEffect';

export const DEFAULT_EFFECTS = [useDragDropEffect];
9 changes: 9 additions & 0 deletions src/app/shared/coordinate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,12 @@ export class Rect implements IRect {
return this.y + this.height;
}
}

export class Point implements IPoint {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}

0 comments on commit 16effa4

Please sign in to comment.