software-mansion / react-native-reanimated

React Native's Animated library reimplemented
https://docs.swmansion.com/react-native-reanimated/
MIT License
9.05k stars 1.31k forks source link

waitFor and simultaneousHandlers do not work with LongPressGestureHandler and PanGestureHandler #1578

Closed Svarto closed 3 years ago

Svarto commented 3 years ago

Description

Adding the option that PanGestureHandler waitFor a LongPressGestureHandler does not work, the PanGestureHandler activates directly. And once LongPressGestureHandler activates, PanGestureHandler deactivates even with simultanousHandler setup according to docs.

Let me know if I have done anything incorrectly, but I have only followed the docs to the best of my ability combining waitFor and simultaneousHandlers...

Screenshots

Steps To Reproduce

  1. Create a new blank project with expo (expo init)
  2. Install Reanimated 2 and Gesture handler (expo install react-native-gesture-handler && npm install react-native-reanimated@2.0.0-rc.0)
  3. Download any image to project-dir/assets/example.jpg
  4. Copy and paste the below code snippet into the App.js and start the expo dev client (expo start -c)
  5. Try and drag the image and longpress - you will see it is reversed from what is expected.

Expected behavior

The PanGestureHandler should waitFor the LongPressGestureHandler to exit the "BEGIN" state before activating, and stay activated once the LongPressGestureHandler activates according to simultaneousHandlers.

Actual behavior

The PanGestureHandler ignores waitFor and simultaneousHandler and activates before LongPressGestureHandler, and deactives once LongPressGestureHandler activates.

Snack or minimal code example

import React from "react";
import { View, Image } from "react-native";
import {
  PanGestureHandler,
  LongPressGestureHandler,
  ScrollView,
} from "react-native-gesture-handler";

import Animated, {
  useAnimatedStyle,
  useAnimatedGestureHandler,
  useSharedValue,
} from "react-native-reanimated";

export default function App() {
  const imageSize = 50;

  const longPressRef = React.createRef();
  const panRef = React.createRef();

  const y = useSharedValue(0);
  const x = useSharedValue(0);
  const onGestureEvent = useAnimatedGestureHandler({
    onStart: (event, ctx) => {
      ctx.offsetX = x.value;
    },
    onActive: (event, ctx) => {
      y.value = event.translationY;
      x.value = event.translationX + ctx.offsetX;
    },
  });

  const style = useAnimatedStyle(() => ({
    position: "absolute",
    top: 0,
    left: 0,
    width: imageSize,
    height: imageSize,
    transform: [{ translateX: x.value }, { translateY: y.value }],
  }));

  return (
    <View
      style={{
        flex: 1,
        paddingTop: 100,
        backgroundColor: "#fff",
        alignItems: "center",
        justifyContent: "center",
      }}
    >
      <ScrollView
        horizontal={true}
        showsHorizontalScrollIndicator={false}
        style={{ positon: "relative", height: imageSize, borderWidth: 1 }}
        contentContainerStyle={{ width: imageSize * 3 }}
      >
        <PanGestureHandler
          ref={panRef}
          simultaneousHandlers={longPressRef}
          waitFor={longPressRef}
          onHandlerStateChange={({ nativeEvent }) =>
            console.log("PANGESTURE ", nativeEvent.state)
          }
          {...{ onGestureEvent }}
        >
          <Animated.View>
            <LongPressGestureHandler
              ref={longPressRef}
              minDurationMs={1000}
              simultaneousHandlers={panRef}
              onHandlerStateChange={({ nativeEvent }) => {
                console.log("LONG PRESS", nativeEvent.state);
                console.log("LONG PRESS, PAN GESTURE SHOULD NOW ACTIVATE");
              }}
            >
              <Animated.View
                style={[
                  {
                    position: "absolute",
                    top: 0,
                    left: 0,
                  },
                  style,
                ]}
              >
                <Image
                  source={require("./assets/example.jpg")}
                  style={{ width: imageSize, height: imageSize }}
                />
              </Animated.View>
            </LongPressGestureHandler>
          </Animated.View>
        </PanGestureHandler>
      </ScrollView>
    </View>
  );
}

Package versions

"expo": "~40.0.0",
"react-native-reanimated": "^2.0.0-rc.0",
"react-native-gesture-handler": "~1.8.0"
github-actions[bot] commented 3 years ago

Issue validator - update # 2

Hello! Congratulations! Your issue passed the validator! Thank you!

Svarto commented 3 years ago

Apologies, this should have been submitted to react-native-gesture-handler, I moved it to there.