Skip to content

[Web] Separate Reanimated from JS#3683

Merged
akwasniewski merged 16 commits into
nextfrom
@akwasniewski/web-extract-reanimated-handlers
Sep 18, 2025
Merged

[Web] Separate Reanimated from JS#3683
akwasniewski merged 16 commits into
nextfrom
@akwasniewski/web-extract-reanimated-handlers

Conversation

@akwasniewski

@akwasniewski akwasniewski commented Aug 21, 2025

Copy link
Copy Markdown
Contributor

Description

Web portion of functionality from PR #3682

Currently we have 2 ways of handling events - Animated and JS/Reanimated. Handling both JS and Reanimated in the same places results in more complex codebase. It also introduces problems with composing gestures. We decided to spit those implementations.

Test plan

import * as React from 'react';
import { Animated, Button } from 'react-native';
import {
  GestureHandlerRootView,
  NativeDetector,
  useGesture,
} from 'react-native-gesture-handler';

export default function App() {
  const [visible, setVisible] = React.useState(true);

  const av = React.useRef(new Animated.Value(0)).current

  const event = Animated.event(
    [{ handlerData: { translationX: av } }],
    {
      useNativeDriver: false,
    }
  );

  const gesture = useGesture('PanGestureHandler', {
    onBegin: (e: unknown) => {
      'worklet';
      console.log('onBegin', e);
    },
    onStart: (e: unknown) => {
      'worklet';
      console.log('onStart', e);
    },
    // onUpdate: event,
    onUpdate: (e: unknown) => {
      'worklet';
      console.log('onUpdate', e);
    },
    onEnd: (e: unknown) => {
      'worklet';
      console.log('onEnd', e);
    },
    onFinalize: (e: unknown) => {
      'worklet';
      console.log('onFinalize', e);
    },
    onTouchesDown: (e: unknown) => {
      'worklet';
      console.log('onTouchesDown', e);
    },
    onTouchesMove: (e: unknown) => {
      'worklet';
      console.log('onTouchesMoved', e);
    },
    onTouchesUp: (e: unknown) => {
      'worklet';
      console.log('onTouchesUp', e);
    },
    onTouchesCancelled: (e: unknown) => {
      'worklet';
      console.log('onTouchesCancelled', e);
    },
  });

  return (
    <GestureHandlerRootView
      style={{ flex: 1, backgroundColor: 'white', paddingTop: 8 }}>
      <Button
        title="Toggle visibility"
        onPress={() => {
          setVisible(!visible);
        }}
      />

      {visible && (
        <NativeDetector gesture={gesture}>
          <Animated.View
            style={[
              {
                width: 150,
                height: 150,
                backgroundColor: 'blue',
                opacity: 0.5,
                borderWidth: 10,
                borderColor: 'green',
                marginTop: 20,
                marginLeft: 40,
              },
              { transform: [{ translateX: av }] },
            ]}
          />
        </NativeDetector>
      )}
    </GestureHandlerRootView>
  );
}

Base automatically changed from @mbert/extract-reanimated-handlers to next September 5, 2025 08:08
@akwasniewski akwasniewski force-pushed the @akwasniewski/web-extract-reanimated-handlers branch from e6644be to 88e36fa Compare September 10, 2025 08:46
@akwasniewski akwasniewski marked this pull request as ready for review September 10, 2025 08:47
@akwasniewski akwasniewski requested a review from m-bert September 10, 2025 08:48
Comment thread packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts Outdated
Comment thread packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts Outdated
Comment thread packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts Outdated
Comment thread packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts Outdated
Comment thread packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts Outdated

@m-bert m-bert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see that in your example, if you use both Animated.Event as onUpdate and touch events, you get the following error:

Uncaught Invariant Violation: Bad event of type undefined for key handlerData
image

Followed by:

Uncaught TypeError: Cannot read properties of undefined (reading 'translationX')
image

Could you investigate that?

Edit: This seems to be the culprit 😅

@akwasniewski

Copy link
Copy Markdown
Contributor Author

I can see that in your example, if you use both Animated.Event as onUpdate and touch events, you get the following error:

Uncaught Invariant Violation: Bad event of type undefined for key handlerData

Thank you! Great catch, It took me a while as I couldn't replicate the error -> it only occurs on chrome. I did not notice that I needed to have attached a condition on where to send the cancel event. I think the error might have been there ever since this PR. It is fixed as of c9c856f.

Comment thread packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts Outdated

@j-piasecki j-piasecki left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (after you include @m-bert's suggestions)

Comment thread packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts Outdated
Comment thread packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts Outdated

@m-bert m-bert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@akwasniewski akwasniewski merged commit ee6107f into next Sep 18, 2025
1 check passed
@akwasniewski akwasniewski deleted the @akwasniewski/web-extract-reanimated-handlers branch September 18, 2025 09:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants