import * as React from 'react'; import { Animated, PanResponder, StyleProp, ViewStyle } from 'react-native'; import { HandlerStateChangeEvent, PanGestureHandler, PanGestureHandlerEventPayload, State, } from 'react-native-gesture-handler'; export type DraggableProps = React.PropsWithChildren<{ containerStyle?: StyleProp; onChangeMoved?: (x: number, y: number) => void; }>; export function Draggable(props: DraggableProps) { const { children, containerStyle } = props; const pan = React.useRef(new Animated.ValueXY()).current; const panResponder = React.useRef( PanResponder.create({ onStartShouldSetPanResponder: () => true, onMoveShouldSetPanResponder: () => true, onPanResponderMove: (_event, gestureState) => { // @ts-ignore const { dx, dy } = gestureState; pan.setValue({ x: dx, y: dy }); }, onPanResponderRelease: () => { pan.flattenOffset(); }, onPanResponderGrant: () => { pan.setOffset({ // @ts-ignore x: pan.x._value, // @ts-ignore y: pan.y._value, }); pan.setValue({ x: 0, y: 0 }); }, }) ).current; return ( {children} ); } export function Draggable2(props: DraggableProps) { const { children, containerStyle, onChangeMoved } = props; const translateXY = React.useRef(new Animated.ValueXY({ x: 0, y: 0 })); const onGestureEvent = Animated.event( [ { nativeEvent: { translationX: translateXY.current.x, translationY: translateXY.current.y, }, }, ], { useNativeDriver: true } ); const onPanHandlerStateChange = ( event: HandlerStateChangeEvent ) => { if (event.nativeEvent.oldState === State.ACTIVE) { translateXY.current.setValue({ x: event.nativeEvent.translationX, y: event.nativeEvent.translationY, }); translateXY.current.flattenOffset(); } else if (event.nativeEvent.oldState === State.UNDETERMINED) { translateXY.current.setOffset({ // @ts-ignore x: translateXY.current.x._value, // @ts-ignore y: translateXY.current.y._value, }); translateXY.current.setValue({ x: 0, y: 0 }); } if (event.nativeEvent.oldState === State.ACTIVE) { onChangeMoved?.( // @ts-ignore translateXY.current.x._value, // @ts-ignore translateXY.current.y._value ); } }; return ( { console.log('dev:Draggable:e:', e.nativeEvent.layout); }} > {children} ); }