-
-
Notifications
You must be signed in to change notification settings - Fork 988
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Emit changes to pointersInside #3348
base: main
Are you sure you want to change the base?
Conversation
Hey, do i understand correctly that you want to detect a touch leaving the handled area, while the handler is still active? I think you should be able to achieve this effect using |
Yes exactly. Since the |
I did some tests comparing Collapsed reproimport React, { useRef } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import {
Gesture,
GestureDetector,
ScrollView,
} from 'react-native-gesture-handler';
import Animated, {
useAnimatedStyle,
useSharedValue,
withSpring,
} from 'react-native-reanimated';
export default function EmptyExample() {
console.log('rerendering');
let measurementStart = useRef(performance.now());
let measurementCount = useRef(0);
const spamCounter = useSharedValue(0);
const highlight = useSharedValue(false);
const animatedStyle = useAnimatedStyle(() => {
measurementCount.current++;
if (measurementCount.current > 10) {
// used to confirm same amount of updates-per-frame occurs both from `onUpdate` and from `spamCounter`
console.log(
'10 updates took:',
(performance.now() - measurementStart.current).toFixed(2),
'ms'
);
measurementCount.current = 0;
measurementStart.current = performance.now();
}
const randomOffset = Math.random() * 2;
if (spamCounter.value > 0) {
spamCounter.value++;
highlight.value = !highlight.value;
}
return {
backgroundColor: highlight.value ? '#f2f2f2' : '#ffcfcf',
transform: [
{
translateX: highlight.value
? withSpring(-randomOffset)
: randomOffset,
},
{
translateY: highlight.value
? -randomOffset
: withSpring(randomOffset),
},
],
};
});
const pan = Gesture.Pan().onUpdate(() => {
highlight.value = !highlight.value;
});
const tap = Gesture.Tap().onStart(() => {
if (spamCounter.value > 0) {
spamCounter.value = 0;
} else {
spamCounter.value++;
}
});
return (
<View style={styles.container}>
<GestureDetector gesture={tap}>
<Animated.View>
<Text style={{ fontSize: 32, opacity: 0.25 }}>
Toggle REA-ONLY spam
</Text>
</Animated.View>
</GestureDetector>
<GestureDetector gesture={pan}>
<Animated.View style={[animatedStyle]}>
<Text style={{ fontSize: 128, opacity: 0.25 }}>🎯</Text>
</Animated.View>
</GestureDetector>
<ScrollView>
{Array(100)
.fill(0)
.map((_, idx) => (
<Animated.View style={[animatedStyle]} key={idx}>
<Text style={{ fontSize: 128, opacity: 0.25 }}>🎯</Text>
</Animated.View>
))}
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
}); Despite this, i think sending out (CC @m-bert @j-piasecki) |
Description
Currently
onHandlerStateChange
will only send events whenever the handler state changes. However for the use case where one wants to resign highlight from the button whenever the user moves their pointer away from it, the only way is to use theonGestureEvent
. This handler is however exceptionally noisy especially on Android, to the extent where I get UI thread frame drops when using worklets.This MR emits additional events for the quite rare case where
pointersInside
prop changes for active gesture handlers to support this use case in a performant way.Test plan