I have an Expo React Native application, and I have two draggable objects which can be dragged simultaneously, at least on iOS, iPhone SE2. On Android, I can drag only one at the time, the second one becomes unchooseable.
import React, { useRef, useState } from 'react';
import { StyleSheet, View } from 'react-native';
import { GestureHandlerRootView, Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { useSharedValue, withTiming, useAnimatedStyle } from 'react-native-reanimated';
import { GLView } from 'expo-gl';
import GameScene from './GameScene';
import Alerts from './scene/Alerts';
import LoadingScreen from './screens/LoadingScreen';
export default function App({ authContext }) {
const [loading, setLoading] = useState(true);
const gameSceneRef = useRef<GameScene | null>(null);
const moveX = useSharedValue(0);
const moveY = useSharedValue(0);
const moveX2 = useSharedValue(0);
const moveY2 = useSharedValue(0);
const camAngle = useSharedValue(0);
const camElev = useSharedValue(0.4);
const panMove = Gesture.Pan()
.onUpdate((e) => {
moveX.value = -e.translationX;
moveY.value = e.translationY;
})
.onEnd(() => {
moveX.value = withTiming(0);
moveY.value = withTiming(0);
});
const panLook = Gesture.Pan()
.onUpdate((e) => {
camAngle.value -= e.translationX * 0.0005;
camElev.value = Math.min(Math.max(camElev.value - e.translationY * 0.0005, 0.1), 1.5);
moveX2.value = -e.translationX;
moveY2.value = e.translationY;
})
.onEnd(() => {
moveX2.value = withTiming(0);
moveY2.value = withTiming(0);
});
const onContextCreate = async (gl) => {
const pixelStorei = gl.pixelStorei.bind(gl);
gl.pixelStorei = function (...args) {
const [parameter] = args;
if (parameter === gl.UNPACK_FLIP_Y_WEBGL) {
return pixelStorei(...args);
}
};
const { drawingBufferWidth: width, drawingBufferHeight: height } = gl;
gameSceneRef.current = new GameScene(gl, width, height);
setLoading(false);
const loop = () => {
requestAnimationFrame(loop);
if (gameSceneRef.current) {
gameSceneRef.current.cameraAngle = camAngle.value;
gameSceneRef.current.cameraElevation = camElev.value;
gameSceneRef.current.setInputs(moveY.value / 8000, -moveX.value / 8000);
gameSceneRef.current.render(gl);
}
};
loop();
};
const animatedStyle1 = useAnimatedStyle(() => ({
transform: [
{ translateX: -moveX.value },
{ translateY: moveY.value },
],
}));
const animatedStyle2 = useAnimatedStyle(() => ({
transform: [
{ translateX: -moveX2.value },
{ translateY: moveY2.value },
],
}));
return (
<>
{loading && <LoadingScreen />}
<GLView style={StyleSheet.absoluteFill} onContextCreate={onContextCreate} />
{!loading && (
<>
<GestureDetector gesture={panMove}>
<Animated.View style={[styles.controlBox,animatedStyle1, { left: 100 }]} />
</GestureDetector>
<GestureDetector gesture={panLook}>
<Animated.View style={[styles.controlBox,animatedStyle2, { right: 100 }]} />
</GestureDetector>
<View style={{ position: 'absolute', right: 50 }}>
<Alerts authContext={authContext} />
</View>
</>
)}
</>
);
}
const styles = StyleSheet.create({
controlBox: {
height: 120,
width: 120,
backgroundColor: '#b58df1',
borderRadius: 20,
position: 'absolute',
bottom: 40,
zIndex: 10,
},
});
This component is wrapped with
<GestureHandlerRootView style={{ flex: 1 }}>
How to fix this issue so I can have multitouch on Android too?
Mark Rotteveel
110k240 gold badges160 silver badges232 bronze badges
asked Nov 15 at 17:25
Bozidar Milivojevic
732 silver badges8 bronze badges