Browse Source

连线坐标修复

yichael 4 months ago
parent
commit
384e1cf4c4
2 changed files with 64 additions and 16 deletions
  1. 54 6
      src/pages/blueprint/canvas/canvas.js
  2. 10 10
      static/processing/测试/bp.json

+ 54 - 6
src/pages/blueprint/canvas/canvas.js

@@ -330,8 +330,58 @@ export function useCanvasLogic(connections, externalControllerRef, nodes = []) {
       return { width: 180, height: isVariable ? 40 : 100 };
     };
     
-    // 计算端口位置(精确对齐到端口中心)
+    // 计算端口位置(精确对齐到端口中心)- 优先从 DOM 获取实际坐标
     const getPortCenterPosition = (node, port, isInput) => {
+      // 尝试从 DOM 获取端口内圆点/箭头的实际位置
+      if (canvasRef.current) {
+        const nodeElement = canvasRef.current.querySelector(`[data-node-id="${node.id}"]`);
+        if (nodeElement) {
+          // 查找所有端口元素
+          const portElements = nodeElement.querySelectorAll('.Blueprint-node-port');
+          
+          // 根据端口类型筛选
+          const isExecutionPort = port.type === 'execution';
+          const matchingPorts = Array.from(portElements).filter(portEl => {
+            const isInputPort = portEl.classList.contains('input');
+            const isOutputPort = portEl.classList.contains('output');
+            const isExecPort = portEl.classList.contains('port-execution');
+            
+            // 匹配方向和类型
+            const directionMatch = (isInput && isInputPort) || (!isInput && isOutputPort);
+            const typeMatch = isExecutionPort ? isExecPort : !isExecPort;
+            
+            return directionMatch && typeMatch;
+          });
+          
+          // 根据端口索引获取对应的端口元素
+          const ports = isInput 
+            ? (node.inputs || []).filter(p => isExecutionPort ? p.type === 'execution' : p.type !== 'execution')
+            : (node.outputs || []).filter(p => isExecutionPort ? p.type === 'execution' : p.type !== 'execution');
+          const portIndex = ports.findIndex(p => p.id === port.id);
+          
+          if (portIndex >= 0 && portIndex < matchingPorts.length) {
+            const portEl = matchingPorts[portIndex];
+            // 查找端口内的圆点或箭头元素
+            const dotElement = portEl.querySelector('.Blueprint-node-port-dot');
+            const arrowElement = portEl.querySelector('.Blueprint-node-port-arrow');
+            const targetElement = dotElement || arrowElement;
+            
+            if (targetElement) {
+              // 获取圆点/箭头相对于画布的位置
+              const targetRect = targetElement.getBoundingClientRect();
+              const canvasRect = canvasRef.current.getBoundingClientRect();
+              
+              // 计算相对于画布的中心坐标,并考虑画布的 transform
+              const centerX = (targetRect.left + targetRect.width / 2 - canvasRect.left) / transform.scale - transform.translateX / transform.scale;
+              const centerY = (targetRect.top + targetRect.height / 2 - canvasRect.top) / transform.scale - transform.translateY / transform.scale;
+              
+              return { x: centerX, y: centerY };
+            }
+          }
+        }
+      }
+      
+      // 如果无法从 DOM 获取,使用计算值作为后备
       const isVariable = node.type === 'variable';
       const nodeDims = getNodeDimensions(node.id);
       
@@ -344,13 +394,9 @@ export function useCanvasLogic(connections, externalControllerRef, nodes = []) {
         
         if (isInput) {
           // Set 变量节点的输入端口(左侧)
-          // CSS: left: -8px,端口容器左边缘在 node.x - 8
-          // 圆点在容器内居中,圆点中心 = node.x - 8 + 8 = node.x
           return { x: node.x - 8 + portContainerHalfWidth, y: portY };
         } else {
           // Get 变量节点的输出端口(右侧)
-          // CSS: right: -8px,端口容器右边缘在 node.x + width + 8
-          // 圆点在容器内居中,圆点中心 = node.x + width + 8 - 8 = node.x + width
           return { x: node.x + nodeDims.width + 8 - portContainerHalfWidth, y: portY };
         }
       } else {
@@ -410,7 +456,9 @@ export function useCanvasLogic(connections, externalControllerRef, nodes = []) {
           
           // 每个端口的Y位置 = 参数区域起始Y + 索引 * (行高 + 间距) + 行高/2
           const paramsStartY = node.y + headerHeight + executionHeight + paramsTopPadding;
-          portCenterY = paramsStartY + dataPortIndex * (portRowHeight + portGap) + portRowHeight / 2;
+          // 增加额外偏移量让Y坐标更准确对齐圆点中心
+          const extraYOffset = 4;
+          portCenterY = paramsStartY + dataPortIndex * (portRowHeight + portGap) + portRowHeight / 2 + extraYOffset;
           
           // 圆点直径12px,半径6px
           const dotRadius = 6;

+ 10 - 10
static/processing/测试/bp.json

@@ -1,20 +1,20 @@
 {
 	"nodePositions": {
-		"node_begin_1768720215708": {
-			"x": 100,
+		"node_begin_1768720932969": {
+			"x": 150,
 			"y": 100
 		},
 		"node_0": {
-			"x": 420,
-			"y": 120
+			"x": 400,
+			"y": 180
 		},
-		"var_get_mini_1768720215708": {
-			"x": 100,
-			"y": 380
+		"var_get_mini_1768720932969": {
+			"x": 60,
+			"y": 360
 		},
-		"var_set_swipeDirection_1768720215708": {
-			"x": 540,
-			"y": 460
+		"var_set_swipeDirection_1768720932969": {
+			"x": 500,
+			"y": 500
 		}
 	}
 }