react-native-reanimated: web: useAnimatedGestureHandler not working

Description

That is working on android, but on the web the gesture event is not called

Screenshots

Steps To Reproduce

const gestureHandler = useAnimatedGestureHandler(
      {
        onStart: (_, ctx: any) => {
          //notCalled
        },
        onActive: (event, ctx) => {
          //notCalled
        },
        onEnd: (_) => {
          //notCalled
        },
      },
      [],
    );

Expected behavior

Actual behavior

Snack or minimal code example

Package versions

  • React: 17.0.1
  • React Native: 0.63.1
  • React Native Reanimated: 2.0.0-alpha.8
  • React Native Gesture Handler: 1.8.0
  • NodeJS: 12

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 5
  • Comments: 17 (11 by maintainers)

Commits related to this issue

Most upvoted comments

This issue seems to have raised its head again, but managed to get it working using the above workaround, as below. I’ve been following along the Expo tutorial to create your first app and ran into this on the gestures step.

const translateX = useSharedValue(0);
const translateY = useSharedValue(0);

// borrowed this from your own source code
const State = {
    UNDETERMINED: 0,
    FAILED: 1,
    BEGAN: 2,
    CANCELLED: 3,
    ACTIVE: 4,
    END: 5,
  };

const gestureHandler = ({ nativeEvent: e }) => {
    if (e.state === State.ACTIVE) {
        translateX.value = e.translationX + e.target.translateX;
        translateY.value = e.translationY + e.target.translateY;
    }
};
const gestureStateHandler = ({ nativeEvent: e }) => {
    if (e.state === State.BEGAN) {
        e.target.translateX = translateX.value;
        e.target.translateY = translateY.value;
    }
};

return (
    <PanGestureHandler onGestureEvent={gestureHandler} onHandlerStateChange={gestureStateHandler}>
        <AnimatedView style={[containerStyle, { translateX: 0, translateY: 0, top: -350 }]}>
            ...the rest of my components
        </AnimatedView>
    </PanGestureHandler>
);

My package.json dependencies are:

"dependencies": {
  "@expo/vector-icons": "^13.0.0",
  "@expo/webpack-config": "^19.0.0",
  "expo": "~49.0.7",
  "expo-image-picker": "~14.3.2",
  "expo-status-bar": "~1.6.0",
  "react": "18.2.0",
  "react-dom": "18.2.0",
  "react-native": "0.72.4",
  "react-native-gesture-handler": "~2.12.0",
  "react-native-reanimated": "~3.3.0",
  "react-native-web": "~0.19.8"
},
"devDependencies": {
  "@babel/core": "^7.20.0",
  "@babel/plugin-proposal-export-namespace-from": "^7.18.9"
},

A single way to fix the first app example is just assign onDrag to PanGestureHandler’s onBegan prop.

This issue seems to have raised its head again, but managed to get it working using the above workaround, as below. I’ve been following along the Expo tutorial to create your first app and ran into this on the gestures step.

const translateX = useSharedValue(0);
const translateY = useSharedValue(0);

// borrowed this from your own source code
const State = {
    UNDETERMINED: 0,
    FAILED: 1,
    BEGAN: 2,
    CANCELLED: 3,
    ACTIVE: 4,
    END: 5,
  };

const gestureHandler = ({ nativeEvent: e }) => {
    if (e.state === State.ACTIVE) {
        translateX.value = e.translationX + e.target.translateX;
        translateY.value = e.translationY + e.target.translateY;
    }
};
const gestureStateHandler = ({ nativeEvent: e }) => {
    if (e.state === State.BEGAN) {
        e.target.translateX = translateX.value;
        e.target.translateY = translateY.value;
    }
};

return (
    <PanGestureHandler onGestureEvent={gestureHandler} onHandlerStateChange={gestureStateHandler}>
        <AnimatedView style={[containerStyle, { translateX: 0, translateY: 0, top: -350 }]}>
            ...the rest of my components
        </AnimatedView>
    </PanGestureHandler>
);

My package.json dependencies are:

"dependencies": {
  "@expo/vector-icons": "^13.0.0",
  "@expo/webpack-config": "^19.0.0",
  "expo": "~49.0.7",
  "expo-image-picker": "~14.3.2",
  "expo-status-bar": "~1.6.0",
  "react": "18.2.0",
  "react-dom": "18.2.0",
  "react-native": "0.72.4",
  "react-native-gesture-handler": "~2.12.0",
  "react-native-reanimated": "~3.3.0",
  "react-native-web": "~0.19.8"
},
"devDependencies": {
  "@babel/core": "^7.20.0",
  "@babel/plugin-proposal-export-namespace-from": "^7.18.9"
},

@ElForastero thanks, I will reopen the issue and soon push the fix 🙌

@karol-bisztyga

Well, I finally made it working on both iOS and Web by manually defining handlers for PanGestureHandler.

useAnimatedGestureHandler works well in native but seems like does absolutely nothing in web environment. Spend a while trying to understand the source of the problem, but with no success.

  const y = useSharedValue(0);
  const startY = useSharedValue(0);

  const gestureHandler = ({ nativeEvent: e }) => {
    'worklet';
    if (e.state === State.ACTIVE) {
      console.log('active');
      y.value = startY.value + e.translationY;
    }
  };

  const gestureStateHandler = ({ nativeEvent: e }) => {
    'worklet';
    if (e.state === State.BEGAN) {
      console.log('began');
      startY.value = y.value;
    }

    if (e.state === State.END) {
      console.log('end');
      y.value = withSpring(0);
    }
  };

return (
<PanGestureHandler onHandlerStateChange={gestureStateHandler} onGestureEvent={gestureHandler}>
        <Animated.View style={[animatedStyle]} />
</PanGestureHandler>
)

“react”: “16.13.1”, “react-native”: “0.63.3”, “react-native-web”: “^0.14.7” “react-native-gesture-handler”: “^1.9.0”, “react-native-reanimated”: “^2.0.0-rc.0”,

UPD:

It looks like the issue is because of this. WorkletEventHandler is being passed into RNGH instead of regular listener. 🤔

image

The issue in RNGH was fixed, but handler still doesn’t work on web.