From 85c018adc1fac039c854aa1a95f4697536588459 Mon Sep 17 00:00:00 2001 From: ddCat <2695092045@qq.com> Date: Wed, 2 Sep 2026 17:00:55 +0800 Subject: [PATCH] =?UTF-8?q?fix(canvas):=20=E7=94=BB=E5=B8=83=E8=BF=9E?= =?UTF-8?q?=E7=BA=BF=20-=20=E4=BF=AE=E5=A4=8D=E8=8A=82=E7=82=B9=E6=8B=96?= =?UTF-8?q?=E5=8A=A8=E6=97=B6=E5=8F=8C=E5=B1=82=E8=B7=AF=E5=BE=84=E5=8F=A0?= =?UTF-8?q?=E5=8A=A0=E6=AE=8B=E5=BD=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/canvas/canvas-connections.tsx | 13 ++++++++----- .../pages/canvas/canvas-project-world-layers.tsx | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/web/src/components/canvas/canvas-connections.tsx b/web/src/components/canvas/canvas-connections.tsx index 6f6c86035..113456915 100644 --- a/web/src/components/canvas/canvas-connections.tsx +++ b/web/src/components/canvas/canvas-connections.tsx @@ -14,6 +14,7 @@ export const ConnectionPath = React.memo(function ConnectionPath({ toScrollTop = 0, active, visualMode = "full", + hideVisual = false, onSelect, onContextMenu, }: { @@ -24,6 +25,7 @@ export const ConnectionPath = React.memo(function ConnectionPath({ toScrollTop?: number; active: boolean; visualMode?: "full" | "hover-only"; + hideVisual?: boolean; onSelect: () => void; onContextMenu?: (event: ReactMouseEvent) => void; }) { @@ -31,12 +33,13 @@ export const ConnectionPath = React.memo(function ConnectionPath({ const [hovered, setHovered] = useState(false); const { pathD, startX, startY, endX, endY } = canvasConnectionPath(connection, from, to, fromScrollTop, toScrollTop); const emphasized = active || hovered; - const showVisual = visualMode === "full" || hovered; + const showVisual = !hideVisual && (visualMode === "full" || hovered); + const showEmphasis = !hideVisual && emphasized; const gradientId = `canvas-flow-${connection.id.replace(/[^a-zA-Z0-9_-]/g, "")}`; return ( - {emphasized ? + {showEmphasis ? @@ -52,7 +55,7 @@ export const ConnectionPath = React.memo(function ConnectionPath({ {/* 光晕:只在强调态渲染。blur 是 filter,成本随线条数量线性上升, 常态几十条线全开会明显掉帧,所以刻意只给悬停/选中的那一条。 垫在底衬描边之下,不改动常态可读性那几层。 */} - {emphasized ? : null} {/* 流光:一小段高亮沿路径跑。周期与虚线流动刻意不同(2.1s vs 1.25s), 两者错拍才像有光在走;同频会锁成一条整体平移的虚线。 */} - {emphasized ? : null} ); -}, (previous, next) => previous.connection === next.connection && previous.from === next.from && previous.to === next.to && previous.active === next.active && previous.visualMode === next.visualMode && previous.fromScrollTop === next.fromScrollTop && previous.toScrollTop === next.toScrollTop); +}, (previous, next) => previous.connection === next.connection && previous.from === next.from && previous.to === next.to && previous.active === next.active && previous.visualMode === next.visualMode && previous.hideVisual === next.hideVisual && previous.fromScrollTop === next.fromScrollTop && previous.toScrollTop === next.toScrollTop); export function canvasConnectionPath(connection: CanvasConnection, from: CanvasNodeData, to: CanvasNodeData, fromScrollTop = 0, toScrollTop = 0) { const startX = from.position.x + from.width; diff --git a/web/src/pages/canvas/canvas-project-world-layers.tsx b/web/src/pages/canvas/canvas-project-world-layers.tsx index 38a49a3cb..e53dcedf7 100644 --- a/web/src/pages/canvas/canvas-project-world-layers.tsx +++ b/web/src/pages/canvas/canvas-project-world-layers.tsx @@ -112,6 +112,8 @@ export const CanvasProjectWorldLayers = memo(function CanvasProjectWorldLayers(p toScrollTop={props.scriptScrollTopById[to.id] || 0} active={props.selectedConnectionId === connection.id || props.relatedConnectionIds.has(connection.id)} visualMode="hover-only" + // 拖动预览由 Leafer 图形层逐帧同步;隐藏这层静态 SVG 描边,避免两套位置叠出残影。 + hideVisual={props.isNodeDragging} onSelect={() => props.onConnectionSelect(connection.id)} onContextMenu={(event) => props.onConnectionContextMenu(event, connection.id)} />