#react-native #react-native-gesture-handler
Вопрос:
Я попытался использовать документы перекрестного обработчика из обработчика жестов react-native.
Я знаю, что это возможно с двумя отдельными элементами, но мне нужен вложенный обработчик жестов панорамирования, так как я пытаюсь выполнить пользовательский захват.
Я пытаюсь создать два обработчика жестов панорамирования и два квадрата. Первый квадрат должен следовать за первым пальцем, а второй квадрат должен следовать за вторым пальцем. Я использовал две PanGestureHandler
буквы «с». Может быть, мне стоит использовать PinchGestureHandler
?
Я вроде как добился этого с помощью этой демонстрации закусок Expo: https://snack.expo.dev/@noitidart/pan-handler-per-finger
Проблемы:
- Первая проблема заключается в том, что 2-й квадрат не следует за 2-м пальцем. Положение 2-го квадрата находится между 1-м и 2-м пальцами.
- Вторая проблема заключается в том, что пока два пальца соприкасаются, затем вы отпускаете 2-й палец, второй квадрат переходит в положение первого.
Возможно ли это?
Вот код для демонстрации закусок, можете скопировать и вставить его в Expo Snack:
import React, { useCallback, useMemo, useRef } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import { PanGestureHandler } from 'react-native-gesture-handler';
import Animated from 'react-native-reanimated';
export default function App() {
const firstFingerState = {
translateX: Animated.useValue(100),
translateY: Animated.useValue(100)
};
const secondFingerState = {
translateX: Animated.useValue(0),
translateY: Animated.useValue(0)
};
const handleFirstFingerHandlerStateChange = useCallback(() => {}, []);
const handleFirstFingerGestureEvent = useCallback(
e => {
firstFingerState.translateX.setValue(e.nativeEvent.x);
firstFingerState.translateY.setValue(e.nativeEvent.y);
},
[firstFingerState.translateX, firstFingerState.translateY]
);
const handleSecondFingerHandlerStateChange = useCallback(() => {}, []);
const handleSecondFingerGestureEvent = useCallback(
e => {
secondFingerState.translateX.setValue(e.nativeEvent.x);
secondFingerState.translateY.setValue(e.nativeEvent.y);
},
[secondFingerState.translateX, secondFingerState.translateY]
);
const firstFingerStyle = useMemo(
() => ({
height: 100,
width: 100,
backgroundColor: 'steelblue',
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
transform: [
{ translateX: firstFingerState.translateX },
{ translateY: firstFingerState.translateY }
]
}),
[firstFingerState.translateX, firstFingerState.translateY]
);
const secondFingerStyle = useMemo(
() => ({
height: 100,
width: 100,
backgroundColor: 'slateblue',
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
transform: [
{ translateX: secondFingerState.translateX },
{ translateY: secondFingerState.translateY }
]
}),
[secondFingerState.translateX, secondFingerState.translateY]
);
const firstFingerPanHandler = useRef();
const secondFingerPanHandler = useRef();
return (
<PanGestureHandler
onGestureEvent={handleFirstFingerGestureEvent}
onHandlerStateChange={handleFirstFingerHandlerStateChange}
ref={firstFingerPanHandler}
simultaneousHandlers={[secondFingerPanHandler]}
// waitFor={[secondFingerPanHandler]}
minPointers={1}
maxPointers={1}
>
<PanGestureHandler
onGestureEvent={handleSecondFingerGestureEvent}
onHandlerStateChange={handleSecondFingerHandlerStateChange}
ref={secondFingerPanHandler}
// simultaneousHandlers={[firstFingerPanHandler]}
// waitFor={[firstFingerPanHandler]}
minPointers={2}
maxPointers={2}
>
<View style={[StyleSheet.absoluteFill]}>
<Animated.View style={firstFingerStyle}>
<Text style={textStyle}>1</Text>
</Animated.View>
<Animated.View style={secondFingerStyle}>
<Text style={textStyle}>2</Text>
</Animated.View>
</View>
</PanGestureHandler>
</PanGestureHandler>
);
}
const textStyle = { fontSize: 54, fontWeight: 'bold', color: '#ffffff' };