I am trying to build a view which is zoomable and scrollable. I was pretty much following the pan and pinch gesture from . The pan gesture works fine but whenever I do the pinch gesture, the app will force quit with no errors.
To replicate the same error, here is what I was doing:
- Create a expo project
npx create-expo-app@latest
- Install react-native-gesture-handler
npx expo install react-native-gesture-handler
- Install yarn
yarn install
- replace the explore.tsx with my code
import React from 'react';
import { Dimensions, StyleSheet, Modal } from 'react-native';
import {
Gesture,
GestureDetector,
GestureHandlerRootView,
} from 'react-native-gesture-handler';
import Animated, {
useSharedValue,
useAnimatedStyle,
} from 'react-native-reanimated';
const { width, height } = Dimensions.get('screen');
function clamp(val:number, min:number, max:number) {
return Math.min(Math.max(val, min), max);
}
export default function TabTwoScreen() {
const scale = useSharedValue(1);
const startScale = useSharedValue(0);
const translationX = useSharedValue(0);
const translationY = useSharedValue(0);
const prevTranslationX = useSharedValue(0);
const prevTranslationY = useSharedValue(0);
const pinch = Gesture.Pinch()
.onStart(() => {
startScale.value = scale.value;
})
.onUpdate((event) => {
scale.value = clamp(
startScale.value * event.scale,
0.5,
Math.min(width / 100, height / 100)
);
console.log(scale.value)
})
const pan = Gesture.Pan()
.onStart(() => {
prevTranslationX.value = translationX.value;
prevTranslationY.value = translationY.value;
})
.onUpdate((event) => {
translationX.value = prevTranslationX.value + event.translationX
translationY.value =prevTranslationY.value + event.translationY
console.log([translationX.value,translationY.value])
})
const boxAnimatedStyles = useAnimatedStyle(() => ({
transform: [
{ scale: scale.value },
{ translateX: translationX.value },
{ translateY: translationY.value }],
}));
const composed = Gesture.Race(pinch,pan);
return (
<GestureHandlerRootView style={styles.container}>
<GestureDetector gesture={composed}>
<Animated.View style={[styles.box, boxAnimatedStyles]}></Animated.View>
</GestureDetector>
</GestureHandlerRootView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
box: {
width: 100,
height: 100,
borderRadius: 20,
backgroundColor: '#b58df1',
},
dot: {
width: 24,
height: 24,
borderRadius: 12,
backgroundColor: '#ccc',
position: 'absolute',
left: '50%',
top: '50%',
pointerEvents: 'none',
},
});
I tried to only include the pinch gesture. The app will still force quit.
const composed = Gesture.Race(pinch);
Please help how should I build a working widget to achieve pinch and pan? Thanks!