diff --git a/src/renderer/components/NodeSelectorPanel/RepresentativeNodeWrapper.tsx b/src/renderer/components/NodeSelectorPanel/RepresentativeNodeWrapper.tsx index ee0e3ff5f..08a8b30b1 100644 --- a/src/renderer/components/NodeSelectorPanel/RepresentativeNodeWrapper.tsx +++ b/src/renderer/components/NodeSelectorPanel/RepresentativeNodeWrapper.tsx @@ -103,11 +103,16 @@ export const RepresentativeNodeWrapper = memo( const createNodeFromSelector = useCallback(() => { if (!reactFlowWrapper.current) return; - const { height: wHeight, width } = reactFlowWrapper.current.getBoundingClientRect(); - - const position = reactFlowInstance.project({ - x: width / 2, - y: wHeight / 2, + const { + height: wHeight, + width, + x, + y, + } = reactFlowWrapper.current.getBoundingClientRect(); + + const position = reactFlowInstance.screenToFlowPosition({ + x: (width + x) / 2, + y: (wHeight + y) / 2, }); createNode({ diff --git a/src/renderer/components/ReactFlowBox.tsx b/src/renderer/components/ReactFlowBox.tsx index 6dc29291d..2bada8c03 100644 --- a/src/renderer/components/ReactFlowBox.tsx +++ b/src/renderer/components/ReactFlowBox.tsx @@ -412,7 +412,7 @@ export const ReactFlowBox = memo(({ wrapperRef, nodeTypes, edgeTypes }: ReactFlo // [setEdges] // ); - const { onConnectStart, onConnectStop, onPaneContextMenu } = usePaneNodeSearchMenu(wrapperRef); + const { onConnectStart, onConnectStop, onPaneContextMenu } = usePaneNodeSearchMenu(); const [selectedNodes, setSelectedNodes] = useState[]>([]); const selectionMenu = useNodesMenu(selectedNodes); diff --git a/src/renderer/contexts/GlobalNodeState.tsx b/src/renderer/contexts/GlobalNodeState.tsx index 5b213c869..98d2d4943 100644 --- a/src/renderer/contexts/GlobalNodeState.tsx +++ b/src/renderer/contexts/GlobalNodeState.tsx @@ -181,7 +181,7 @@ export const GlobalProvider = memo( setNodes: rfSetNodes, setEdges: rfSetEdges, viewportInitialized, - project, + screenToFlowPosition, } = useReactFlow(); const currentViewport = useViewport(); @@ -1231,8 +1231,14 @@ export const GlobalProvider = memo( copyToClipboard(getNodes(), getEdges()); }, [getNodes, getEdges]); const pasteFn = useCallback(() => { - pasteFromClipboard(changeNodes, changeEdges, createNode, project, reactFlowWrapper); - }, [changeNodes, changeEdges, createNode, project, reactFlowWrapper]); + pasteFromClipboard( + changeNodes, + changeEdges, + createNode, + screenToFlowPosition, + reactFlowWrapper + ); + }, [changeNodes, changeEdges, createNode, screenToFlowPosition, reactFlowWrapper]); const selectAllFn = useCallback(() => { changeNodes((nodes) => nodes.map((n) => ({ ...n, selected: true }))); changeEdges((edges) => edges.map((e) => ({ ...e, selected: true }))); diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index 133048018..3297e0b74 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -56,7 +56,7 @@ export const pasteFromClipboard = ( setNodes: SetState[]>, setEdges: SetState[]>, createNode: (proto: NodeProto, parentId?: string) => void, - project: Project, + screenToFlowPosition: Project, reactFlowWrapper: React.RefObject ) => { const availableFormats = clipboard.availableFormats(); @@ -114,14 +114,14 @@ export const pasteFromClipboard = ( let positionX = 0; let positionY = 0; if (reactFlowWrapper.current) { - const { height, width } = + const { height, width, x, y } = reactFlowWrapper.current.getBoundingClientRect(); - positionX = width / 2; - positionY = height / 2; + positionX = (width + x) / 2; + positionY = (height + y) / 2; } createNode({ nodeType: 'regularNode', - position: project({ x: positionX, y: positionY }), + position: screenToFlowPosition({ x: positionX, y: positionY }), data: { schemaId: 'chainner:image:load' as SchemaId, inputData: { diff --git a/src/renderer/hooks/usePaneNodeSearchMenu.tsx b/src/renderer/hooks/usePaneNodeSearchMenu.tsx index 3853e93e7..63e735d47 100644 --- a/src/renderer/hooks/usePaneNodeSearchMenu.tsx +++ b/src/renderer/hooks/usePaneNodeSearchMenu.tsx @@ -379,9 +379,7 @@ interface Position { readonly y: number; } -export const usePaneNodeSearchMenu = ( - wrapperRef: React.RefObject -): UsePaneNodeSearchMenuValue => { +export const usePaneNodeSearchMenu = (): UsePaneNodeSearchMenuValue => { const typeState = useContextSelector(GlobalVolatileContext, (c) => c.typeState); const useConnectingFrom = useContextSelector(GlobalVolatileContext, (c) => c.useConnectingFrom); const { createNode, createConnection } = useContext(GlobalContext); @@ -393,7 +391,7 @@ export const usePaneNodeSearchMenu = ( const [connectingFrom, setConnectingFrom] = useState(null); const [, setGlobalConnectingFrom] = useConnectingFrom; - const { getNode, project, getNodes, getEdges } = useReactFlow(); + const { getNode, screenToFlowPosition, getNodes, getEdges } = useReactFlow(); const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 }); @@ -428,12 +426,8 @@ export const usePaneNodeSearchMenu = ( const onSchemaSelect = useCallback( (schema: NodeSchema, target: ConnectionTarget) => { - const reactFlowBounds = wrapperRef.current!.getBoundingClientRect(); const { x, y } = mousePosition; - const projPosition = project({ - x: x - reactFlowBounds.left, - y: y - reactFlowBounds.top, - }); + const projPosition = screenToFlowPosition({ x, y }); const nodeId = createUniqueId(); createNode({ id: nodeId, @@ -483,9 +477,8 @@ export const usePaneNodeSearchMenu = ( createNode, functionDefinitions, mousePosition, - project, + screenToFlowPosition, setGlobalConnectingFrom, - wrapperRef, ] );