fix(canvas): 画布连线 - 修复节点拖动时双层路径叠加残影
This commit is contained in:
@@ -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<SVGPathElement>) => 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 (
|
||||
<g>
|
||||
{emphasized ? <defs>
|
||||
{showEmphasis ? <defs>
|
||||
<linearGradient id={gradientId} gradientUnits="userSpaceOnUse" x1={startX} y1={startY} x2={endX} y2={endY}>
|
||||
<stop offset="0%" stopColor={theme.node.muted} stopOpacity={0.18} />
|
||||
<stop offset="48%" stopColor={theme.accent.primary} stopOpacity={0.58} />
|
||||
@@ -52,7 +55,7 @@ export const ConnectionPath = React.memo(function ConnectionPath({
|
||||
{/* 光晕:只在强调态渲染。blur 是 filter,成本随线条数量线性上升,
|
||||
常态几十条线全开会明显掉帧,所以刻意只给悬停/选中的那一条。
|
||||
垫在底衬描边之下,不改动常态可读性那几层。 */}
|
||||
{emphasized ? <path
|
||||
{showEmphasis ? <path
|
||||
d={pathD}
|
||||
stroke={theme.accent.primary}
|
||||
strokeWidth="8"
|
||||
@@ -123,7 +126,7 @@ export const ConnectionPath = React.memo(function ConnectionPath({
|
||||
/> : null}
|
||||
{/* 流光:一小段高亮沿路径跑。周期与虚线流动刻意不同(2.1s vs 1.25s),
|
||||
两者错拍才像有光在走;同频会锁成一条整体平移的虚线。 */}
|
||||
{emphasized ? <path
|
||||
{showEmphasis ? <path
|
||||
className="canvas-connection-comet"
|
||||
d={pathD}
|
||||
stroke={`url(#${gradientId}-comet)`}
|
||||
@@ -136,7 +139,7 @@ export const ConnectionPath = React.memo(function ConnectionPath({
|
||||
/> : null}
|
||||
</g>
|
||||
);
|
||||
}, (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;
|
||||
|
||||
@@ -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)}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user