Skip to content

Nested Pinch and Rotate gestures are triggered via a single pointer [Android][New Arch] #3611

@wen-kai

Description

@wen-kai

Description

Hey there! First off, incredible work, thank you for all of your amazing efforts.

We have a component that handles pan, zoom, and rotation which we've used for years on the old architecture. We rewrote the component to migrate to the latest reanimated/gesture handler APIs which is working perfectly with the old architecture. It is also working perfectly with the new architecture in IOS; however, for Android there are some unexpected behaviours. In our production app the Gestures are nested -- this is for modularity and easier to maintain code. After debugging it appears on Android all 3 gestures are triggered regardless of numberOfPointers, and numberOfPointers appears to always return 1 (including zoom and rotate).

What you'll find in the repro is on Android, the begin events are triggered for Pinch and Rotate even when Panning via 1 pointer and they always return 1 for numberOfPointers. So it appears Pinch and Rotate onBegin is being called prematurely before 2 pointers are recognized which may lead to incorrect anchor/focal coordinates -- this causes strange jumping behavior in our production app because we use these events and values to handle pan/zoom/rotate based on focal/anchor points.

I've tried to communicate the repro via logs and screen recording. The logs show the bug while the screen recording just shows what is generating the logs. The repro gestures are very basic so it doesn't show the jumping we see in production; however, you'll see the numberOfPointers is always 1 and rotate/pinch events are called even when just panning with a single pointer. The expected result (shown via ios below) is that pinch/rotate events should only fire when numberOfPointers > 1.

This only happens on Android in the New Architecture. Unfortunately this is a major blocker for us to migrate to the new architecture. Hopefully a fix will help maintain consistency between platforms and architectures for better expected results. Please let me know if I can provide more info. Thank you!

Steps to reproduce

Build

  1. Clone repo
  2. Run yarn install
  3. expo prebuild
  4. npx expo run:android

Repro

  1. Drag square
  2. Pinch square
  3. Drag square
  4. Rotate square
  5. Pan

Actual Logs (android):
*note numberOfPointers is always 1

//// PAN ////
 LOG  rotate gesture began 1
 LOG  pan gesture began 1
 LOG  pinch gesture began 1
 LOG  pan gesture ended
 LOG  ------------------
//// PINCH ////
 LOG  rotate gesture began 1
 LOG  pan gesture began 1
 LOG  pinch gesture began 1
 LOG  pinch gesture ended
 LOG  rotate gesture began 1
//// PAN ////
 LOG  pan gesture began 1
 LOG  pinch gesture began 1
 LOG  pan gesture ended
 LOG  ------------------
//// ROTATE ////
 LOG  rotate gesture began 1
 LOG  pan gesture began 1
 LOG  pinch gesture began 1
 LOG  pan gesture ended
 LOG  ------------------
//// ROTATE ////
 LOG  rotate gesture began 1
 LOG  pan gesture began 1
 LOG  pinch gesture began 1
 LOG  pinch gesture ended
 LOG  rotate gesture ended
//// PAN ////
 LOG  rotate gesture began 1
 LOG  pan gesture began 1
 LOG  pinch gesture began 1
 LOG  pan gesture ended
 LOG  ------------------
Screen_Recording_20250713_212647_expo-reanimated-test.1.mp4

Expected Logs (ios):
*note numberOfPointers is correct for each gesture
*note pan/pinch events are never triggered during panning

//// PAN ////
 LOG  pan gesture began 1
 LOG  pan gesture ended
 LOG  ------------------
//// PINCH ////
 LOG  pan gesture began 2
 LOG  pinch gesture began 2
 LOG  pinch gesture ended
//// PAN ////
 LOG  pan gesture began 1
 LOG  pan gesture ended
 LOG  ------------------
//// ROTATE ////
 LOG  pan gesture began 2
 LOG  rotate gesture began 2
 LOG  rotate gesture ended
//// PAN ////
 LOG  pan gesture began 1
 LOG  pan gesture ended
 LOG  ------------------
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2025-07-13.at.16.00.57.mp4

A link to a Gist, an Expo Snack or a link to a repository based on this template that reproduces the bug.

https://github.com/wen-kai/reanimated-android-newarch-bug

Gesture Handler version

2.24.0

React Native version

0.79.5

Platforms

Android

JavaScript runtime

Hermes

Workflow

Using Expo Prebuild or an Expo development build

Architecture

New Architecture (Fabric)

Build type

Debug mode

Device

Real device

Device model

Samsung Galaxy s23 ultra (android 15)

Acknowledgements

Yes

Metadata

Metadata

Assignees

No one assigned

    Labels

    Platform: AndroidThis issue is specific to AndroidRepro providedA reproduction with a snack or repo is provided

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions