tongyy / react-native-draggable

Draggable Item
MIT License
314 stars 89 forks source link

Saving new positions to state after drag #89

Open ugrdursun opened 3 years ago

ugrdursun commented 3 years ago

Hello, firstly thanks for this beautiful library

I couldnt figure out how to get new positions of draggable after drag or while dragging to save state. I use latest version.

  state={
    elements: [
      {
        id:'somenode1',
        type:'node',
        position_x: 190,
        position_y: 150,
        node_width: 160,
        node_height: 60,
        data: {
          title:'CHILD1'
        }
      },

...
      <>
      <View style={{backgroundColor:'#bbe1fa', borderTopColor:'#b8b5ff', height:SCREEN_HEIGHT, width:SCREEN_WIDTH, flex:1}}>

                {this.state.elements.map((item, key) =>  {

                          return (

                            <Draggable

                          onDragRelease={(e,g,b) => {

                            this.dragNode(item, g.moveX, g.moveY)

                          } }
                          x={item.position_x}
                          y={item.position_y}
                          z={1000}

......
  dragNode = (node, newX, newY) => {

    var elements = this.state.elements

           var newNode = node

            //REMOVE THE NODE
            var newElements = elements.filter(item2 => item2.id != node.id)

            //EDIT POSITIONS
            newNode.position_x = newX
            newNode.position_y = newY

            //PUSH NEW ONE
            console.log(newNode)
            newElements.push(newNode)

            //SET AS STATE
            this.setState({elements:newElements})

  }

Its not working properly this way, going crazy and draggable places some irrevelant places

I think as you know better the problem is g.moveX is returning touch positions. But i want to get latest position of draggable after drag. Draggable works smooth, I just want to pass latest positions to state to store them.

Thanks for your support

garrylachman commented 3 years ago

Thanks for workaround

ugrdursun commented 3 years ago

Thanks for workaround

Its not actually a "workaround". nodes going crazy after release

garrylachman commented 3 years ago

So you remove and re-add them... this is classic workaround for a problem. its not direct solution that fixed the problem why they go crazy - its a workaround to "bypass" the issue

LiLPandemio commented 3 years ago

Same problem here, I tried everything with no success and pageX and locationx is sooo confusing :( Did you managed to do it? @baconcheese113 @tongyy Do you know how can we achive that? I need help :(

ugrdursun commented 3 years ago

Same problem here, I tried everything with no success and pageX and locationx is sooo confusing :( Did you managed to do it? @baconcheese113 @tongyy Do you know how can we achive that? I need help :(

Still could not find the solution. Library smoothly dragging item to wherever we want but X Y outputs are not matching with wrappers X Y

paul-leymet commented 3 years ago

Hello,

From my experience with this library, it appears that there are some internal X/Y stored values in it (offsets ?) that are not reinitialized when passing new X/Y props.

It may result in having the draggable going to crazy places after releasing the drag.

The only solution i found is similar to your workaround :

Hope that this will help someone as i've been stucked for a while on this !

ugrdursun commented 3 years ago

Hello,

From my experience with this library, it appears that there are some internal X/Y stored values in it (offsets ?) that are not reinitialized when passing new X/Y props.

It may result in having the draggable going to crazy places after releasing the drag.

The only solution i found is similar to your workaround :

  • add a "key" prop based of the value you pass on X and Y in the Draggable component.
  • this will force to destroy and recreate the component based on the new X and Y values.

Hope that this will help someone as i've been stucked for a while on this !

Thanks for idea. I am currently trying to solve this issue right now.

onDragRelease={(event, gestureState, bounds) => { console.log(bounds.top , bounds.left)

Actually bounds prop working more stable than gestureState due I think its returning current position inside wrapper. But this one also changing position some X Y position after saving to state. Also its bad bounds is not a prop of onDrag :(

Audeos commented 3 years ago

Did you find any solutions? I'm having the same problem. Dragging works fine but trying to save the positions on onDragRelease makes the image jump.

KolbySisk commented 3 years ago

I'm also running into this problem.

matteosprintdigital commented 3 years ago

Hello,

From my experience with this library, it appears that there are some internal X/Y stored values in it (offsets ?) that are not reinitialized when passing new X/Y props.

It may result in having the draggable going to crazy places after releasing the drag.

The only solution i found is similar to your workaround :

  • add a "key" prop based of the value you pass on X and Y in the Draggable component.
  • this will force to destroy and recreate the component based on the new X and Y values.

Hope that this will help someone as i've been stucked for a while on this !

Thanks for the workaround! As Paul says, just add to your Draggable a key prop and pass to it a value that changes every time you complete the action. You can use also x,y unless you are moving perfectly on of those directions. Alternatively you can use Date.now()

Create first a state to hold this value which trigger the re-render of the entire Draggable. const [reloader, setReloader] = React.useState<number>(Date.now());

Add the value as a key to your draggable. <Draggable key={reloader} />

Set the state every time you want the entire object to be re-rendered, for example inside the function that you call in onDragRelease setReloader(Date.now());

Just remember that this still a workaround and it might not be the best way to go :)