Skip to content

Commit 5d60a09

Browse files
authored
[Web] Fix Pinch and Rotation (#4078)
## Description I've noticed that `Pinch` and `Rotation` behave weirdly when it comes to ending gesture on web. I've took a look and fixed some minor issues. > [!NOTE] > This PR may introduce mismatch between `android` and `web` versions of `Rotation`. I still think that this is how it is supposed to work, so we may want to [make required changes to `android` as well](#4079) (or drop this PR if you prefer to). ### Pinch I've noticed that `Pinch` is not reset when pointers are placed on view and then released. This was because for some reason `Pinch` simply ignored finished states if it had not activated earlier. ### Rotation `Rotation`, always finalized with `true`. This was because we always tried to move it to `end` state. Our internal event handler hadn't been sending `onDeactivate`, but `true` was still passed into `onFinalize`. ## Test plan <details> <summary>Tested on Transformations example and code below:</summary> ```tsx import { StyleSheet, View } from 'react-native'; import { GestureDetector, GestureHandlerRootView, usePinchGesture, useRotationGesture, } from 'react-native-gesture-handler'; export default function App() { const g = useRotationGesture({ onBegin: () => console.log('onBegin'), onActivate: () => console.log('onActivate'), onUpdate: (e) => console.log('onUpdate', e.rotation), onDeactivate: () => console.log('onDeactivate'), onFinalize: (_, s) => console.log('onFinalize', s), }); return ( <GestureHandlerRootView style={styles.container}> <GestureDetector gesture={g}> <View style={styles.box} /> </GestureDetector> </GestureHandlerRootView> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', }, box: { width: 200, height: 200, backgroundColor: 'blue', borderRadius: 12, }, }); ``` </details>
1 parent b09afc0 commit 5d60a09

3 files changed

Lines changed: 13 additions & 22 deletions

File tree

packages/react-native-gesture-handler/src/web/detectors/RotationGestureDetector.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,11 @@ export default class RotationGestureDetector
7575
}
7676

7777
private finish(): void {
78-
if (!this.isInProgress) {
79-
return;
78+
if (this.isInProgress) {
79+
this.isInProgress = false;
80+
this.keyPointers = [NaN, NaN];
8081
}
8182

82-
this.isInProgress = false;
83-
this.keyPointers = [NaN, NaN];
8483
this.onRotationEnd(this);
8584
}
8685

@@ -138,9 +137,8 @@ export default class RotationGestureDetector
138137
break;
139138

140139
case EventTypes.UP:
141-
if (this.isInProgress) {
142-
this.finish();
143-
}
140+
this.finish();
141+
144142
break;
145143
}
146144

packages/react-native-gesture-handler/src/web/handlers/PinchGestureHandler.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,11 @@ export default class PinchGestureHandler extends GestureHandler {
9898
protected override onPointerUp(event: AdaptedEvent): void {
9999
super.onPointerUp(event);
100100
this.tracker.removeFromTracker(event.pointerId);
101-
if (this.state !== State.ACTIVE) {
102-
return;
103-
}
104-
this.scaleGestureDetector.onTouchEvent(event, this.tracker);
105101

106102
if (this.state === State.ACTIVE) {
103+
// We don't have to call it in the else branch as it would simply return `true`.
104+
this.scaleGestureDetector.onTouchEvent(event, this.tracker);
105+
107106
this.end();
108107
} else {
109108
this.fail();

packages/react-native-gesture-handler/src/web/handlers/RotationGestureHandler.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ export default class RotationGestureHandler extends GestureHandler {
4141
return true;
4242
},
4343
onRotationEnd: (_detector: RotationGestureDetector): void => {
44-
this.end();
44+
if (this.state === State.ACTIVE) {
45+
this.end();
46+
} else {
47+
this.fail();
48+
}
4549
},
4650
};
4751

@@ -136,16 +140,6 @@ export default class RotationGestureHandler extends GestureHandler {
136140
super.onPointerUp(event);
137141
this.tracker.removeFromTracker(event.pointerId);
138142
this.rotationGestureDetector.onTouchEvent(event, this.tracker);
139-
140-
if (this.state !== State.ACTIVE) {
141-
return;
142-
}
143-
144-
if (this.state === State.ACTIVE) {
145-
this.end();
146-
} else {
147-
this.fail();
148-
}
149143
}
150144

151145
protected override onPointerRemove(event: AdaptedEvent): void {

0 commit comments

Comments
 (0)