|
@@ -1,7 +1,7 @@
|
|
|
-import {Position, useVueFlow} from '@vue-flow/core'
|
|
|
-import { ref, watch } from 'vue'
|
|
|
-import type { Node, Edge } from '@vue-flow/core';
|
|
|
-import {HJInterNodeData, HJPosition} from "../types/comTypes";
|
|
|
+import { Position, useVueFlow } from "@vue-flow/core";
|
|
|
+import { ref, watch } from "vue";
|
|
|
+import type { Node, Edge } from "@vue-flow/core";
|
|
|
+import { HJInterNodeData, HJPosition } from "../types/comTypes";
|
|
|
|
|
|
import { v4 as uuidv4 } from "uuid";
|
|
|
|
|
@@ -9,7 +9,7 @@ import { v4 as uuidv4 } from "uuid";
|
|
|
* @returns {string} - A unique id.
|
|
|
*/
|
|
|
function getId(): string {
|
|
|
- return uuidv4();
|
|
|
+ return uuidv4();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -17,129 +17,132 @@ function getId(): string {
|
|
|
* @type {{draggedType: Ref<string|null>, isDragOver: Ref<boolean>, isDragging: Ref<boolean>}}
|
|
|
*/
|
|
|
const state = {
|
|
|
- /**
|
|
|
- * The type of the node being dragged.
|
|
|
- */
|
|
|
- dragData: ref<HJInterNodeData | null>(null),
|
|
|
- draggedType: ref<string | null>(null),
|
|
|
- isDragOver: ref(false),
|
|
|
- isDragging: ref(false),
|
|
|
-}
|
|
|
+ /**
|
|
|
+ * The type of the node being dragged.
|
|
|
+ */
|
|
|
+ dragData: ref<HJInterNodeData | null>(null),
|
|
|
+ draggedType: ref<string | null>(null),
|
|
|
+ isDragOver: ref(false),
|
|
|
+ isDragging: ref(false),
|
|
|
+};
|
|
|
|
|
|
export default function useDragAndDrop() {
|
|
|
- const { draggedType, isDragOver, isDragging , dragData} = state
|
|
|
-
|
|
|
- const { addNodes, screenToFlowCoordinate, onNodesInitialized, updateNode } = useVueFlow()
|
|
|
+ const { draggedType, isDragOver, isDragging, dragData } = state;
|
|
|
|
|
|
- watch(isDragging, (dragging) => {
|
|
|
- document.body.style.userSelect = dragging ? 'none' : ''
|
|
|
- })
|
|
|
+ const { addNodes, screenToFlowCoordinate, onNodesInitialized, updateNode } =
|
|
|
+ useVueFlow();
|
|
|
|
|
|
- // 第二个类型是HJInterNodeData
|
|
|
- function onDragStart(event: DragEvent, data: HJInterNodeData) {
|
|
|
- if (event.dataTransfer) {
|
|
|
- event.dataTransfer.setData('application/vueflow', data.type!)
|
|
|
- event.dataTransfer.effectAllowed = 'move'
|
|
|
- }
|
|
|
+ watch(isDragging, (dragging) => {
|
|
|
+ document.body.style.userSelect = dragging ? "none" : "";
|
|
|
+ });
|
|
|
|
|
|
- draggedType.value = data.type!
|
|
|
- dragData.value = data
|
|
|
- isDragging.value = true
|
|
|
-
|
|
|
- document.addEventListener('drop', onDragEnd)
|
|
|
+ // 第二个类型是HJInterNodeData
|
|
|
+ function onDragStart(event: DragEvent, data: HJInterNodeData) {
|
|
|
+ if (event.dataTransfer) {
|
|
|
+ event.dataTransfer.setData("application/vueflow", data.type!);
|
|
|
+ event.dataTransfer.effectAllowed = "move";
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Handles the drag over event.
|
|
|
- *
|
|
|
- * @param {DragEvent} event
|
|
|
- */
|
|
|
- function onDragOver(event: DragEvent) {
|
|
|
- event.preventDefault()
|
|
|
+ draggedType.value = data.type!;
|
|
|
+ dragData.value = JSON.parse(JSON.stringify(data));
|
|
|
+ isDragging.value = true;
|
|
|
|
|
|
- if (draggedType.value) {
|
|
|
- isDragOver.value = true
|
|
|
+ document.addEventListener("drop", onDragEnd);
|
|
|
+ }
|
|
|
|
|
|
- if (event.dataTransfer) {
|
|
|
- event.dataTransfer.dropEffect = 'move'
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * Handles the drag over event.
|
|
|
+ *
|
|
|
+ * @param {DragEvent} event
|
|
|
+ */
|
|
|
+ function onDragOver(event: DragEvent) {
|
|
|
+ event.preventDefault();
|
|
|
|
|
|
- function onDragLeave() {
|
|
|
- isDragOver.value = false
|
|
|
- }
|
|
|
+ if (draggedType.value) {
|
|
|
+ isDragOver.value = true;
|
|
|
|
|
|
- function onDragEnd() {
|
|
|
- isDragging.value = false
|
|
|
- isDragOver.value = false
|
|
|
- draggedType.value = null
|
|
|
- dragData.value = null
|
|
|
- document.removeEventListener('drop', onDragEnd)
|
|
|
+ if (event.dataTransfer) {
|
|
|
+ event.dataTransfer.dropEffect = "move";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function onDragLeave() {
|
|
|
+ isDragOver.value = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ function onDragEnd() {
|
|
|
+ isDragging.value = false;
|
|
|
+ isDragOver.value = false;
|
|
|
+ draggedType.value = null;
|
|
|
+ dragData.value = null;
|
|
|
+ document.removeEventListener("drop", onDragEnd);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Handles the drop event.
|
|
|
+ *
|
|
|
+ * @param {DragEvent} event
|
|
|
+ */
|
|
|
+ function onDrop(event: DragEvent) {
|
|
|
+ const position = screenToFlowCoordinate({
|
|
|
+ x: event.clientX,
|
|
|
+ y: event.clientY,
|
|
|
+ });
|
|
|
+
|
|
|
+ const nodeId = getId();
|
|
|
+
|
|
|
+ const newNode: Node = {
|
|
|
+ id: nodeId,
|
|
|
+ position,
|
|
|
+ data: JSON.parse(JSON.stringify(dragData.value)).data,
|
|
|
+ type: JSON.parse(JSON.stringify(dragData.value)).type,
|
|
|
+ targetPosition: Position.Top,
|
|
|
+ sourcePosition: Position.Bottom,
|
|
|
+ };
|
|
|
+
|
|
|
+ console.log("从左侧拖拽的添加操作", newNode);
|
|
|
+ // 如果没有给node的data设置handles属性,这默认上下结构
|
|
|
+ if (!newNode.data.handles) {
|
|
|
+ newNode.data.handles = [
|
|
|
+ {
|
|
|
+ type: "source",
|
|
|
+ position: HJPosition.Bottom,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "target",
|
|
|
+ position: HJPosition.Top,
|
|
|
+ },
|
|
|
+ ];
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Handles the drop event.
|
|
|
+ * Align node position after drop, so it's centered to the mouse
|
|
|
*
|
|
|
- * @param {DragEvent} event
|
|
|
+ * We can hook into events even in a callback, and we can remove the event listener after it's been called.
|
|
|
*/
|
|
|
- function onDrop(event: DragEvent) {
|
|
|
- const position = screenToFlowCoordinate({
|
|
|
- x: event.clientX,
|
|
|
- y: event.clientY,
|
|
|
- })
|
|
|
-
|
|
|
- const nodeId = getId()
|
|
|
-
|
|
|
- const newNode: Node = {
|
|
|
- id: nodeId,
|
|
|
- position,
|
|
|
- data: dragData.value!.data,
|
|
|
- type: dragData.value!.type,
|
|
|
- targetPosition: Position.Top,
|
|
|
- sourcePosition: Position.Bottom,
|
|
|
- }
|
|
|
-
|
|
|
- console.log("从左侧拖拽的添加操作",newNode)
|
|
|
- // 如果没有给node的data设置handles属性,这默认上下结构
|
|
|
- if (!newNode.data.handles) {
|
|
|
- newNode.data.handles = [
|
|
|
- {
|
|
|
- type: 'source',
|
|
|
- position: HJPosition.Bottom,
|
|
|
-
|
|
|
- },
|
|
|
- {
|
|
|
- type: 'target',
|
|
|
- position: HJPosition.Top,
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Align node position after drop, so it's centered to the mouse
|
|
|
- *
|
|
|
- * We can hook into events even in a callback, and we can remove the event listener after it's been called.
|
|
|
- */
|
|
|
- const { off } = onNodesInitialized(() => {
|
|
|
- updateNode(nodeId, (node) => ({
|
|
|
- position: { x: node.position.x - 100, y: node.position.y - node.dimensions.height / 2 },
|
|
|
- }))
|
|
|
-
|
|
|
- off()
|
|
|
- })
|
|
|
-
|
|
|
- addNodes(newNode)
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- draggedType,
|
|
|
- isDragOver,
|
|
|
- isDragging,
|
|
|
- onDragStart,
|
|
|
- onDragLeave,
|
|
|
- onDragOver,
|
|
|
- onDrop,
|
|
|
- }
|
|
|
+ const { off } = onNodesInitialized(() => {
|
|
|
+ updateNode(nodeId, (node) => ({
|
|
|
+ position: {
|
|
|
+ x: node.position.x - 100,
|
|
|
+ y: node.position.y - node.dimensions.height / 2,
|
|
|
+ },
|
|
|
+ }));
|
|
|
+
|
|
|
+ off();
|
|
|
+ });
|
|
|
+
|
|
|
+ addNodes(newNode);
|
|
|
+ draggedType.value = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ draggedType,
|
|
|
+ isDragOver,
|
|
|
+ isDragging,
|
|
|
+ onDragStart,
|
|
|
+ onDragLeave,
|
|
|
+ onDragOver,
|
|
|
+ onDrop,
|
|
|
+ };
|
|
|
}
|