UNPKG

@tamagui/react-native-web-lite

Version:
164 lines (163 loc) 8.56 kB
import { InteractionManager } from "@tamagui/react-native-web-internals"; import TouchHistoryMath from "../vendor/react-native/TouchHistoryMath/index.native.js"; var { currentCentroidX, currentCentroidY, currentCentroidXOfTouchesChangedAfter, currentCentroidYOfTouchesChangedAfter, previousCentroidXOfTouchesChangedAfter, previousCentroidYOfTouchesChangedAfter } = TouchHistoryMath, PanResponder = { _initializeGestureState(gestureState) { gestureState.x = 0, gestureState.y = 0, gestureState.initialX = 0, gestureState.initialY = 0, gestureState.deltaX = 0, gestureState.deltaY = 0, gestureState.velocityX = 0, gestureState.velocityY = 0, gestureState.numberActiveTouches = 0, gestureState._accountsForMovesUpTo = 0; }, /** * Take all recently moved touches, calculate how the centroid has changed just for those * recently moved touches, and append that change to an accumulator. This is * to (at least) handle the case where the user is moving three fingers, and * then one of the fingers stops but the other two continue. * * This is very different than taking all of the recently moved touches and * storing their centroid as `dx/dy`. For correctness, we must *accumulate * changes* in the centroid of recently moved touches. * * There is also some nuance with how we handle multiple moved touches in a * single event. Multiple touches generate two 'move' events, each of * them triggering `onResponderMove`. But with the way `PanResponder` works, * all of the gesture inference is performed on the first dispatch, since it * looks at all of the touches. Therefore, `PanResponder` does not call * `onResponderMove` passed the first dispatch. This diverges from the * typical responder callback pattern (without using `PanResponder`), but * avoids more dispatches than necessary. * * When moving two touches in opposite directions, the cumulative * distance is zero in each dimension. When two touches move in parallel five * pixels in the same direction, the cumulative distance is five, not ten. If * two touches start, one moves five in a direction, then stops and the other * touch moves fives in the same direction, the cumulative distance is ten. * * This logic requires a kind of processing of time "clusters" of touch events * so that two touch moves that essentially occur in parallel but move every * other frame respectively, are considered part of the same movement. * * x/y: If a move event has been observed, `(x, y)` is the centroid of the most * recently moved "cluster" of active touches. * deltaX/deltaY: Cumulative touch distance. Accounts for touch moves that are * clustered together in time, moving the same direction. Only valid when * currently responder (otherwise, it only represents the drag distance below * the threshold). */ _updateGestureStateOnMove(gestureState, touchHistory) { var movedAfter = gestureState._accountsForMovesUpTo, prevX = previousCentroidXOfTouchesChangedAfter(touchHistory, movedAfter), prevY = previousCentroidYOfTouchesChangedAfter(touchHistory, movedAfter), prevDeltaX = gestureState.deltaX, prevDeltaY = gestureState.deltaY, x = currentCentroidXOfTouchesChangedAfter(touchHistory, movedAfter), y = currentCentroidYOfTouchesChangedAfter(touchHistory, movedAfter), deltaX = prevDeltaX + (x - prevX), deltaY = prevDeltaY + (y - prevY), dt = touchHistory.mostRecentTimeStamp - gestureState._accountsForMovesUpTo; gestureState.deltaX = deltaX, gestureState.deltaY = deltaY, gestureState.numberActiveTouches = touchHistory.numberActiveTouches, gestureState.velocityX = (deltaX - prevDeltaX) / dt, gestureState.velocityY = (deltaY - prevDeltaY) / dt, gestureState.x = x, gestureState.y = y, gestureState._accountsForMovesUpTo = touchHistory.mostRecentTimeStamp; }, /** * Enhanced versions of all of the responder callbacks that provide not only * the `ResponderEvent`, but also the `PanResponder` gesture state. * * In general, for events that have capture equivalents, we update the * gestureState once in the capture phase and can use it in the bubble phase * as well. */ create(config) { var interactionState = { handle: null }, gestureState = { // Useful for debugging stateID: Math.random(), x: 0, y: 0, initialX: 0, initialY: 0, deltaX: 0, deltaY: 0, velocityX: 0, velocityY: 0, numberActiveTouches: 0, _accountsForMovesUpTo: 0 }, { onStartShouldSetResponder, onStartShouldSetResponderCapture, onMoveShouldSetResponder, onMoveShouldSetResponderCapture, onPanGrant, onPanStart, onPanMove, onPanEnd, onPanRelease, onPanReject, onPanTerminate, onPanTerminationRequest } = config, panHandlers = { onStartShouldSetResponder(event) { return onStartShouldSetResponder != null ? onStartShouldSetResponder(event, gestureState) : !1; }, onMoveShouldSetResponder(event) { return onMoveShouldSetResponder != null ? onMoveShouldSetResponder(event, gestureState) : !1; }, onStartShouldSetResponderCapture(event) { return event.nativeEvent.touches.length === 1 && PanResponder._initializeGestureState(gestureState), gestureState.numberActiveTouches = event.touchHistory.numberActiveTouches, onStartShouldSetResponderCapture != null ? onStartShouldSetResponderCapture(event, gestureState) : !1; }, onMoveShouldSetResponderCapture(event) { var touchHistory = event.touchHistory; return PanResponder._updateGestureStateOnMove(gestureState, touchHistory), onMoveShouldSetResponderCapture != null ? onMoveShouldSetResponderCapture(event, gestureState) : !1; }, onResponderGrant(event) { interactionState.handle || (interactionState.handle = InteractionManager.createInteractionHandle()), gestureState.initialX = currentCentroidX(event.touchHistory), gestureState.initialY = currentCentroidY(event.touchHistory), gestureState.deltaX = 0, gestureState.deltaY = 0, onPanGrant?.(event, gestureState); }, onResponderReject(event) { clearInteractionHandle(interactionState, onPanReject, event, gestureState); }, onResponderStart(event) { var { numberActiveTouches } = event.touchHistory; gestureState.numberActiveTouches = numberActiveTouches, onPanStart?.(event, gestureState); }, onResponderMove(event) { var touchHistory = event.touchHistory; gestureState._accountsForMovesUpTo !== touchHistory.mostRecentTimeStamp && (PanResponder._updateGestureStateOnMove(gestureState, touchHistory), onPanMove?.(event, gestureState)); }, onResponderEnd(event) { var { numberActiveTouches } = event.touchHistory; gestureState.numberActiveTouches = numberActiveTouches, clearInteractionHandle(interactionState, onPanEnd, event, gestureState); }, onResponderRelease(event) { clearInteractionHandle(interactionState, onPanRelease, event, gestureState), PanResponder._initializeGestureState(gestureState); }, onResponderTerminate(event) { clearInteractionHandle(interactionState, onPanTerminate, event, gestureState), PanResponder._initializeGestureState(gestureState); }, onResponderTerminationRequest(event) { return onPanTerminationRequest != null ? onPanTerminationRequest(event, gestureState) : !0; } }; return { panHandlers, getInteractionHandle() { return interactionState.handle; } }; } }; function clearInteractionHandle(interactionState, callback, event, gestureState) { interactionState.handle && (InteractionManager.clearInteractionHandle(interactionState.handle), interactionState.handle = null), callback && callback(event, gestureState); } var Alternative_default = PanResponder; export { Alternative_default as default }; //# sourceMappingURL=Alternative.js.map