|
|
@@ -5,6 +5,12 @@
|
|
|
import { useEffect, useRef, useState } from 'react';
|
|
|
import { initCanvasController } from '../utils/canvas-controller.js';
|
|
|
import { ConnectionManager } from '../utils/connection-manager.js';
|
|
|
+import {
|
|
|
+ useNodeDrag,
|
|
|
+ handleNodeDragStart,
|
|
|
+ handleNodeDragMove,
|
|
|
+ handleNodeDragEnd
|
|
|
+} from '../node-renderer/node-renderer.js';
|
|
|
|
|
|
/**
|
|
|
* 画布逻辑钩子
|
|
|
@@ -20,12 +26,17 @@ export function useCanvasLogic(connections, externalControllerRef, nodes = []) {
|
|
|
const [transform, setTransform] = useState({ scale: 1, translateX: 0, translateY: 0 });
|
|
|
const [connectingStart, setConnectingStart] = useState(null);
|
|
|
const [connectingEnd, setConnectingEnd] = useState(null);
|
|
|
- const [draggedNodeId, setDraggedNodeId] = useState(null);
|
|
|
- const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
|
|
|
|
|
|
- // 使用 ref 来存储拖拽状态,避免闭包陷阱
|
|
|
- const draggedNodeIdRef = useRef(null);
|
|
|
- const dragOffsetRef = useRef({ x: 0, y: 0 });
|
|
|
+ // 使用节点拖拽管理 hook(集中管理拖拽逻辑)
|
|
|
+ const {
|
|
|
+ draggedNodeId,
|
|
|
+ dragOffset,
|
|
|
+ startDrag,
|
|
|
+ endDrag,
|
|
|
+ isDragging,
|
|
|
+ getDraggedNodeId,
|
|
|
+ getDragOffset
|
|
|
+ } = useNodeDrag();
|
|
|
|
|
|
// 初始化画布控制器
|
|
|
useEffect(() => {
|
|
|
@@ -367,46 +378,19 @@ export function useCanvasLogic(connections, externalControllerRef, nodes = []) {
|
|
|
|
|
|
/**
|
|
|
* 处理节点鼠标按下(开始拖拽)
|
|
|
+ * 使用 node-renderer.js 中的统一逻辑
|
|
|
*/
|
|
|
const handleNodeMouseDown = (e, nodeId, nodes, selectedNodeIds, onNodeSelect) => {
|
|
|
- if (e.button !== 0) return;
|
|
|
-
|
|
|
const node = nodes.find(n => n.id === nodeId);
|
|
|
if (!node) return;
|
|
|
|
|
|
const rect = canvasRef.current.getBoundingClientRect();
|
|
|
- const canvasX = (e.clientX - rect.left - transform.translateX) / transform.scale;
|
|
|
- const canvasY = (e.clientY - rect.top - transform.translateY) / transform.scale;
|
|
|
-
|
|
|
- const offset = {
|
|
|
- x: canvasX - node.x,
|
|
|
- y: canvasY - node.y
|
|
|
- };
|
|
|
-
|
|
|
- // 同时更新 state 和 ref,确保所有闭包都能访问到最新值
|
|
|
- setDraggedNodeId(nodeId);
|
|
|
- setDragOffset(offset);
|
|
|
- draggedNodeIdRef.current = nodeId;
|
|
|
- dragOffsetRef.current = offset;
|
|
|
-
|
|
|
- // 将 cursor 应用到 document.body,确保在边界外也保持 grabbing
|
|
|
- document.body.style.cursor = 'grabbing';
|
|
|
- document.body.style.userSelect = 'none';
|
|
|
-
|
|
|
- if (e.ctrlKey || e.metaKey) {
|
|
|
- onNodeSelect?.(nodeId, true);
|
|
|
- } else {
|
|
|
- if (!selectedNodeIds.includes(nodeId)) {
|
|
|
- onNodeSelect?.(nodeId, false);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- e.preventDefault();
|
|
|
- e.stopPropagation();
|
|
|
+ handleNodeDragStart(e, node, rect, transform, startDrag, onNodeSelect, selectedNodeIds);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 处理鼠标移动(连线预览、节点拖拽)
|
|
|
+ * 使用 node-renderer.js 中的统一逻辑
|
|
|
*/
|
|
|
const handleMouseMove = (e, onNodeMove) => {
|
|
|
const rect = canvasRef.current.getBoundingClientRect();
|
|
|
@@ -422,34 +406,17 @@ export function useCanvasLogic(connections, externalControllerRef, nodes = []) {
|
|
|
setConnectingEnd({ x, y });
|
|
|
}
|
|
|
|
|
|
- // 使用 ref 来检查拖拽状态,避免闭包问题
|
|
|
- if (draggedNodeIdRef.current) {
|
|
|
- // 计算节点在画布坐标系中的新位置
|
|
|
- const containerX = e.clientX - rect.left;
|
|
|
- const containerY = e.clientY - rect.top;
|
|
|
- const canvasX = (containerX - transform.translateX) / transform.scale - dragOffsetRef.current.x;
|
|
|
- const canvasY = (containerY - transform.translateY) / transform.scale - dragOffsetRef.current.y;
|
|
|
-
|
|
|
- onNodeMove?.(draggedNodeIdRef.current, canvasX, canvasY);
|
|
|
- }
|
|
|
+ // 使用 node-renderer.js 中的拖拽处理逻辑
|
|
|
+ handleNodeDragMove(e, rect, transform, getDraggedNodeId, getDragOffset, onNodeMove);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 处理鼠标释放
|
|
|
+ * 使用 node-renderer.js 中的统一逻辑
|
|
|
*/
|
|
|
const handleMouseUp = (e) => {
|
|
|
- // 使用 ref 来检查拖拽状态,避免闭包问题
|
|
|
- if (draggedNodeIdRef.current) {
|
|
|
- // 恢复 document.body 的 cursor 样式
|
|
|
- document.body.style.cursor = '';
|
|
|
- document.body.style.userSelect = '';
|
|
|
-
|
|
|
- // 同时清除 state 和 ref
|
|
|
- setDraggedNodeId(null);
|
|
|
- setDragOffset({ x: 0, y: 0 });
|
|
|
- draggedNodeIdRef.current = null;
|
|
|
- dragOffsetRef.current = { x: 0, y: 0 };
|
|
|
- }
|
|
|
+ // 使用 node-renderer.js 中的拖拽结束逻辑
|
|
|
+ handleNodeDragEnd(endDrag);
|
|
|
|
|
|
// 如果正在连线但没有连接到端口,取消连线
|
|
|
if (connectingStart) {
|