John M.
John M.

Reputation: 307

Create a draggable, re-sizable box in React Native

I've searched all over for a way to create a View that has both draggable and resizable functionality. I have come close with the react-native-gesture-handler package but the resizable corners are where I'm left stumped.

<PanGestureHandler
                onGestureEvent={this._onDragGestureEvent}
                onHandlerStateChange={this._onDragHandlerStateChange}
            >
                <Animated.View style={styles.wrapper}>
                    <RotationGestureHandler
                        ref={this.rotationRef}
                        simultaneousHandlers={this.pinchRef}
                        onGestureEvent={this._onRotateGestureEvent}
                        onHandlerStateChange={this._onRotateHandlerStateChange}>
                        <Animated.View style={styles.wrapper}>
                            <PinchGestureHandler
                                ref={this.pinchRef}
                                simultaneousHandlers={this.rotationRef}
                                onGestureEvent={this._onPinchGestureEvent}
                                onHandlerStateChange={this._onPinchHandlerStateChange}>
                                <Animated.View collapsable={false}>
                                    <Image background={true} width={Dimensions.get('window').width}
                                           source={{ uri: `<BACKGROUND IMAGE>` }}
                                           defaultSource={require('../../assets/icon.png')}>
                                        <Animated.View
                                            style={[
                                                styles.box,
                                                {
                                                    width: this.state.boxWidth,
                                                    height: this.state.boxHeight,
                                                    transform: [
                                                        { perspective: 200 },
                                                        { scale: this._scale },
                                                        { rotate: this._rotateStr },
                                                        { rotateX: this._tiltStr },
                                                        { translateX: this._translateX },
                                                        { translateY: this._translateY }
                                                    ],
                                                },
                                            ]}
                                        />
                                    </Image>
                                </Animated.View>
                            </PinchGestureHandler>
                        </Animated.View>
                    </RotationGestureHandler>
                </Animated.View>
            </PanGestureHandler>

My question is has anyone ever come across or has an example of resizable corner handles in React Native?

Upvotes: 1

Views: 2386

Answers (2)

Lakmal
Lakmal

Reputation: 928

try this.

import React, { useRef, useState } from 'react';
import { Animated, PanResponder, View } from 'react-native';

const DragableCorner = () => {
  const [initialHeight, setInitialHeight] = useState(100);
  const lastHeight = useRef(initialHeight); // Store the last height
  const animatedHeight = useRef(new Animated.Value(initialHeight)).current;

  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onMoveShouldSetPanResponder: () => true, // Ensure it captures move gestures
      onPanResponderMove: (_, gestureState) => {
        // Update animated height based on the last height and the change in y-direction
        const newHeight = lastHeight.current + gestureState.dy;
        animatedHeight.setValue(newHeight);
      },
      onPanResponderRelease: (_, gestureState) => {
        // Update the last height on release
        const newHeight = lastHeight.current + gestureState.dy;
        lastHeight.current = newHeight;
        setInitialHeight(newHeight); // Optionally update initialHeight if needed
      },
      onPanResponderTerminationRequest: () => false, // Prevent other components from becoming the responder
    })
  ).current;

  return (
    <View style={{ flex: 1, backgroundColor: 'transparent' }}>
      <Animated.View
        style={{ height: animatedHeight, backgroundColor: 'skyblue', flex: 1 }}
      >
        {/* Content */}
      </Animated.View>
      <View style={{ height: 10, backgroundColor: 'blue' }} {...panResponder.panHandlers} />
    </View>
  );
};

export default DragableCorner;

Upvotes: 0

DavidBiller
DavidBiller

Reputation: 71

check this:

https://github.com/brucelin0325/react-native-resizable-flex-panes/blob/master/Mycomponent.js

the componentWillMount() will help you i guess?

Upvotes: 1

Related Questions