Обработчик панорамирования на палец, направляющий два квадрата

#react-native #react-native-gesture-handler

Вопрос:

Я попытался использовать документы перекрестного обработчика из обработчика жестов react-native.

Я знаю, что это возможно с двумя отдельными элементами, но мне нужен вложенный обработчик жестов панорамирования, так как я пытаюсь выполнить пользовательский захват.

Я пытаюсь создать два обработчика жестов панорамирования и два квадрата. Первый квадрат должен следовать за первым пальцем, а второй квадрат должен следовать за вторым пальцем. Я использовал две PanGestureHandler буквы «с». Может быть, мне стоит использовать PinchGestureHandler ?

Я вроде как добился этого с помощью этой демонстрации закусок Expo: https://snack.expo.dev/@noitidart/pan-handler-per-finger

Проблемы:

  1. Первая проблема заключается в том, что 2-й квадрат не следует за 2-м пальцем. Положение 2-го квадрата находится между 1-м и 2-м пальцами.
  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' };