The docs say:
Simply set
manualActivation
to true on a PanGesture and use StateManager to fail the gesture if the user attempts to drag the component sooner than the duration of the long press.
However, I can't figure out how to measure timing in the callbacks of the PanGesture
, because the app crashes if I try to use setTimeout
, and even if I were able to use setTimeout
, I can't get a reference to the GestureStateManager
except in the touch callbacks, so I'm not sure how to move the gesture into the START
state.
Is there a tool besides setTimeout
that I can use to implement a timer in what seems to be an RN Reanimated worklet? For example, can I use performance.now()
?
Here's what I have so far:
const isPressed = useSharedValue(false);
const isDragging = useSharedValue(false);
const start = useSharedValue({
x: 0,
y: 0,
});
const offset = useSharedValue({
x: 0,
y: 0,
});
const gesture =
Gesture.Pan()
.manualActivation(true)
.onBegin((evt) => {
console.log('pan begin');
})
.onStart(() => {
console.log('pan start');
isPressed.value = true;
offset.value = {
x: 0,
y: 0,
};
})
.onTouchesDown((evt, state) => {
if (evt.numberOfTouches !== 1) {
state.fail();
}
isPressed.value = true;
start.value = {
x: evt.allTouches[0].x,
y: evt.allTouches[0].y,
};
// using setTimeout here causes a crash, and using runOnJS doesn't fix it
// runOnJS(setTimeout)(() => {
// isDragging.value = true;
// state.activate();
// }, 500);
})
.onTouchesMove((evt, state) => {
isPressed.value = true;
const offsetX = start.value.x - evt.allTouches[0].x;
const offsetY = start.value.y - evt.allTouches[0].y;
const dist = Math.sqrt(offsetX * offsetX + offsetY * offsetY);
if (dist > 10) {
state.fail();
}
})
.onUpdate((evt) => {
offset.value = {
x: evt.translationX,
y: evt.translationY,
};
})
.onFinalize(() => {
offset.value = {
x: 0,
y: 0,
};
isPressed.value = false;
isDragging.value = false;
console.log('pan finalize');
});