react-native-gesture-handler#GestureDetector TypeScript Examples
The following examples show how to use
react-native-gesture-handler#GestureDetector.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ProgressBar.tsx From jellyfin-audio-player with MIT License | 4 votes |
function ProgressBar() {
const { position, buffered, duration } = useProgress();
const width = useSharedValue(0);
const pos = useSharedValue(0);
const buf = useSharedValue(0);
const dur = useSharedValue(0);
const isDragging = useSharedValue(false);
const offset = useSharedValue(0);
const bufferAnimation = useDerivedValue(() => {
return calculateProgressTranslation(buf.value, dur.value, width.value);
}, [[dur, buf, width.value]]);
const progressAnimation = useDerivedValue(() => {
if (isDragging.value) {
return calculateProgressTranslation(offset.value, width.value, width.value);
} else {
return calculateProgressTranslation(pos.value, dur.value, width.value);
}
});
const timePassed = useDerivedValue(() => {
if (isDragging.value) {
const currentPosition = (offset.value - DRAG_HANDLE_SIZE / 2) / (width.value - DRAG_HANDLE_SIZE) * dur.value;
return getMinutes(currentPosition) + ':' + getSeconds(currentPosition);
} else {
return getMinutes(pos.value) + ':' + getSeconds(pos.value);
}
}, [pos]);
const timeRemaining = useDerivedValue(() => {
if (isDragging.value) {
const currentPosition = (offset.value - DRAG_HANDLE_SIZE / 2) / (width.value - DRAG_HANDLE_SIZE) * dur.value;
const remaining = (currentPosition - dur.value) * -1;
return `-${getMinutes(remaining)}:${getSeconds((remaining))}`;
} else {
const remaining = (pos.value - dur.value) * -1;
return `-${getMinutes(remaining)}:${getSeconds((remaining))}`;
}
}, [pos, dur]);
const pan = Gesture.Pan()
.minDistance(1)
.activeOffsetX(1)
.activeOffsetY(1)
.onBegin((e) => {
isDragging.value = true;
offset.value = Math.min(Math.max(DRAG_HANDLE_SIZE / 2, e.x), width.value - DRAG_HANDLE_SIZE / 2);
}).onUpdate((e) => {
offset.value = Math.min(Math.max(DRAG_HANDLE_SIZE / 2, e.x), width.value - DRAG_HANDLE_SIZE / 2);
}).onFinalize(() => {
pos.value = (offset.value - DRAG_HANDLE_SIZE / 2) / (width.value - DRAG_HANDLE_SIZE) * dur.value;
isDragging.value = false;
runOnJS(TrackPlayer.seekTo)(pos.value);
});
const tap = Gesture.Tap()
.onBegin((e) => {
isDragging.value = true;
offset.value = Math.min(Math.max(DRAG_HANDLE_SIZE / 2, e.x), width.value - DRAG_HANDLE_SIZE / 2);
}).onFinalize(() => {
pos.value = (offset.value - DRAG_HANDLE_SIZE / 2) / (width.value - DRAG_HANDLE_SIZE) * dur.value;
isDragging.value = false;
runOnJS(TrackPlayer.seekTo)(pos.value);
});
const gesture = Gesture.Exclusive(pan, tap);
useEffect(() => {
pos.value = position;
buf.value = buffered;
dur.value = duration;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [position, buffered, duration]);
const dragHandleStyles = useAnimatedStyle(() => {
return {
transform: [
{ translateX: offset.value },
{
scale: withTiming(isDragging.value ? 1 : 0, {
duration: 100,
easing: Easing.out(Easing.ease),
})
}
],
};
});
const bufferStyles = useAnimatedStyle(() => ({
transform: [
{ translateX: bufferAnimation.value }
]
}));
const progressStyles = useAnimatedStyle(() => {
return {
transform: [
{ translateX: progressAnimation.value }
]
};
});
const timePassedStyles = useAnimatedStyle(() => {
return {
transform: [
{ translateY: withTiming(isDragging.value && offset.value < 48 ? 12 : 0, {
duration: 145,
easing: Easing.ease
}) },
],
};
});
const timeRemainingStyles = useAnimatedStyle(() => {
return {
transform: [
{ translateY: withTiming(isDragging.value && offset.value > width.value - 48 ? 12 : 0, {
duration: 150,
easing: Easing.ease
}) },
],
};
});
return (
<GestureDetector gesture={gesture}>
<Container onLayout={(e) => { width.value = e.nativeEvent.layout.width; }}>
<ProgressTrackContainer>
<ProgressTrack
opacity={0.15}
/>
<ProgressTrack
style={bufferStyles}
opacity={0.15}
/>
<ProgressTrack
style={progressStyles}
/>
</ProgressTrackContainer>
<DragHandle style={dragHandleStyles} />
<NumberBar style={{ flex: 1 }}>
<Number text={timePassed} style={timePassedStyles} />
<Number text={timeRemaining} style={timeRemainingStyles} />
</NumberBar>
</Container>
</GestureDetector>
);
}