Search code examples
react-nativedrag-and-dropsimultaneous

Multiple drag and drop simultaneous in React Native


Hello i'm creating a game in react native and i'm stuck because i wan't both players can drag and drop horizontaly an element in same time on the same phone.

I have two components like that:

export class Player1 extends Component{
    constructor(props){
        super(props);

        this.state = {  
            pan             : new Animated.ValueXY()
        };
    }
    componentWillMount(){
        this.panResponder = PanResponder.create({    
            onMoveShouldSetResponderCapture : () => true,
            onMoveShouldSetPanResponderCapture : () => true,

            onPanResponderGrant : (e, gestureState) => {
                this.state.pan.setOffset({x: this.state.pan.x._value, y: this.state.pan.y._value});
                this.state.pan.setValue({x: 0, y: 0});
            },

            onPanResponderMove : Animated.event([null,{ 
                dx : this.state.pan.x,
            }]),
            onPanResponderRelease: (e, {vx, vy}) => {
            }
        });
    }


    render(){
        return (
                <View style={styles.mainContainer}>
                    {this.renderDraggable()}
                </View>
        );
    }

    renderDraggable(){
        return (
                <View style={styles.draggableContainer}>
                    <Animated.View                  
                    style={[this.state.pan.getLayout(), styles.triangle]}
                    {...this.panResponder.panHandlers}   > 
                    </Animated.View>
            </View>

        );
}
}

And in my screen i call my components like that:

export default function HomeScreen() {
  return (
    <View>
     <Player1></Player1>
     <Player2></Player2>
    </View>
  );
}

Thanks for your help


Solution

  • I found a solution, i used react-native-gesture-handle like in the directory doubleDraggable of the example: https://kmagiera.github.io/react-native-gesture-handler/docs/example.html

    My Code:

    import React, { Component } from 'react';
    import { Animated, StyleSheet, View } from 'react-native';
    
    import {
      PanGestureHandler,
      ScrollView,
      State,
    } from 'react-native-gesture-handler';
    
    
    export class Players extends Component {
      constructor(props) {
        super(props);
        this._translateX = new Animated.Value(0);
        this._translateY = new Animated.Value(0);
        this._lastOffset = { x: 0, y: 0 };
        this._onGestureEvent = Animated.event(
          [
            {
              nativeEvent: {
                translationX: this._translateX,
    
              },
            },
          ],
    
        );
      }
      _onHandlerStateChange = event => {
        if (event.nativeEvent.oldState === State.ACTIVE) {
          this._lastOffset.x += event.nativeEvent.translationX;
          this._translateX.setOffset(this._lastOffset.x);
          this._translateX.setValue(0);
          this._translateY.setOffset(this._lastOffset.y);
          this._translateY.setValue(0);
        }
      };
      render() {
        return (
          <PanGestureHandler
            {...this.props}
            onGestureEvent={this._onGestureEvent}
            onHandlerStateChange={this._onHandlerStateChange}>
            <Animated.View
              style={[
                styles.box,
                {
                  transform: [
                    { translateX: this._translateX },
                    { translateY: this._translateY },
                  ],
                },
                this.props.boxStyle,
              ]}
            />
          </PanGestureHandler>
        );
      }
    }
    
    export default class Example extends Component {
      render() {
        return (
          <View style={styles.scrollView}>
            <DraggableBox />
          </View>
        );
      }
    }
    
    const styles = StyleSheet.create({
      scrollView: {
        flex: 1,
      },
      box: {
        position: 'absolute',
        width: 0,
        height: 0,
        backgroundColor: 'transparent',
        borderStyle: 'solid',
        borderLeftWidth: 25,
        borderRightWidth: 25,
        borderBottomWidth: 50,
        borderLeftColor: 'transparent',
        borderRightColor: 'transparent',
      },
    });
    

    And Screen:

    <View styles={styles.container}>
      <Players boxStyle={styles.player1}></Players>
      <Players boxStyle={styles.player2}></Players>
    </View>