I’m building a throttle control using React Native. The issue is when I initially touch the throttle handle, it teleports to a different position rather than staying at the point of contact and dragging smoothly. I’m trying to achieve a realistic, friction-based throttle movement, but the handle jumps to the bottom/top upon the first touch. I need the handle to start from where it is touched and drag smoothly without teleporting.
Here is a video of the problem:
Also here is my Throttle.js file :-
import React, { useRef, useState } from 'react';
import { View, PanResponder, Animated, StyleSheet } from 'react-native';
const ThrottleLever = ({ onMove }) => {
const [throttle, setThrottle] = useState(0.5); // Initialize throttle at midpoint (0.5)
const panY = useRef(new Animated.Value(0)).current; // Track Y-axis
const THRESHOLD = 10; // Minimum pixels to move before reacting
const SENSITIVITY = 0.5; // Scale factor to reduce sensitivity
const panResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderMove: (e, gestureState) => {
// Ignore small movements
if (Math.abs(gestureState.dy) < THRESHOLD) return;
// Scale the Y movement
let scaledY = gestureState.dy * SENSITIVITY;
let newY = Math.max(-100, Math.min(100, scaledY));
// Convert Y-axis value from -100 to 100 range to 0 to 1 range
let mappedY = (newY + 100) / 200;
panY.setValue(newY); // Set Y-axis value (for UI movement)
setThrottle(mappedY); // Update the throttle (0 to 1)
onMove(mappedY); // Send the 0 to 1 value to the parent
},
onPanResponderRelease: (e, gestureState) => {
// On release, apply friction-like effect
let finalY = Math.max(-100, Math.min(100, gestureState.dy * SENSITIVITY));
let finalMappedY = (finalY + 100) / 200; // Map -100 to 1
setThrottle(finalMappedY);
onMove(finalMappedY); // Send final 0 to 1 value to parent
// Apply a friction-like animation to smoothly settle the lever
Animated.spring(panY, {
toValue: finalY, // Final position
friction: 2, // Higher friction for a slower response
tension: 20, // Lower tension for a softer spring
useNativeDriver: false,
}).start();
}
})
).current;
return (
<View style={styles.leverBase}>
<Animated.View
{...panResponder.panHandlers}
style={[
styles.leverHandle,
{ transform: [{ translateY: panY }] } // Only Y-axis movement
]}
/>
</View>
);
};
const styles = StyleSheet.create({
leverBase: {
width: 60,
height: 250,
backgroundColor: '#888',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
overflow: 'hidden', // Prevent lever handle from moving outside the base
},
leverHandle: {
width: 40,
height: 40,
backgroundColor: 'blue',
borderRadius: 10,
},
});
export default ThrottleLever;
I implemented a throttle lever using PanResponder in React Native, and it works smoothly when dragging. However, when I touch the handle, it teleports to the top or bottom before I even drag it. Since this is meant to simulate an aircraft throttle lever, this teleportation can cause serious fluctuations in throttle control, making it unusable for realistic applications. I need help making the handle follow the touch point smoothly without jumping when pressed.
Shamil is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.