Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get relative node position on Edge Drop for new node with parentNode #4152

Open
TrySpace opened this issue Apr 13, 2024 · 1 comment
Open
Labels
feature request New feature or request

Comments

@TrySpace
Copy link

TrySpace commented Apr 13, 2024

Please describe the feature that you want to propose

I'm trying to use the Add Node On Edge Drop example and have the newNode add a parentNode: connectingNodeId.current prop so it will automatically belong to its parent.

But I can't figure out how to calculate the relative position because event.clientX is the absolute position which is not the one I need when it uses the parentNode's relative position.

I would like a way to get the relative position or to subtract the parentNode's x/y coords somehow?
I saw this issue #3393 but I don't want to use absolute positioning for the grouped/parented nodes.

See sandbox

It could be achieved if the OnConnectEnd event would have a node besides the event from which I could simply extract the position or 'absolutePosition` from. That node would be the node that I connect from.

/Update
I've tried to use useRef to store the origin node and calculate the position, but I can't get it to work right

@TrySpace TrySpace added the feature request New feature or request label Apr 13, 2024
@TrySpace TrySpace changed the title Get relative node position on Edge Drop for grouped nodes Get relative node position on Edge Drop for new node with parentNode Apr 13, 2024
@TrySpace
Copy link
Author

TrySpace commented May 2, 2024

What's working for me right now is this:

 const onConnectStart: OnConnectStart = useCallback((evt, node) => {
    const { nodeId } = node
    const pNode = nodeId ? getNode(nodeId) : {}
    // @ts-ignore
    parentNode.current = pNode
    connectingNodeId.current = nodeId
  }, [])

  const onConnectEnd: OnConnectEnd = useCallback(
    (event) => {
      if (!connectingNodeId.current) return

      const targetIsPane = (event.target as Element).classList.contains(
        'react-flow__pane'
      )

      if (targetIsPane) {
        // Get mouse position
        // @ts-ignore
        const clientX = (event?.clientX as number) || 0
        // @ts-ignore
        const clientY = (event?.clientY as number) || 0

        // Convert mouse coordinates to relative position
        const screenPos = screenToFlowPosition({
          x: clientX,
          y: clientY,
        })

        // Get the absolute position of the parent node (if any)
        const parentX = parentNode.current?.positionAbsolute?.x || 0
        const parentY = parentNode.current?.positionAbsolute?.y || 0

        // Subtract parent coords from relative screenPos
        const posX = screenPos.x - parentX
        const posY = screenPos.y - parentY

        const newId = getId()

        const newNode = NewNode({
          id: newId,
          position: { x: posX, y: posY },
          parentId: connectingNodeId.current,
        })

        setNodes((nds) => nds.concat(newNode))

        setEdges((eds) =>
          // @ts-ignore
          eds.concat({
            id: newId,
            source: connectingNodeId.current,
            target: newId,
          })
        )
      }
    },
    [screenToFlowPosition]
  )

This won't work anymore when I upgrade to v12 though...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant