UNPKG

react-native-full-calendars

Version:

React Native Full Calendar (RNFC) is an intuitive and powerful calendar component library designed for React Native.

107 lines (99 loc) 3.74 kB
"use strict"; import { useContext } from 'react'; import { Gesture } from 'react-native-gesture-handler'; import { Easing, useDerivedValue, useSharedValue, withTiming } from 'react-native-reanimated'; import { SwiperContext } from '../store'; export const usePanGesture = ({ curIndex, translate, viewSize }) => { const { props } = useContext(SwiperContext); const { minIndex, maxIndex, vertical, initialIndex } = props; // Derived values for animation boundaries const minIndexAnim = useDerivedValue(() => minIndex, [minIndex]); const maxIndexAnim = useDerivedValue(() => maxIndex, [maxIndex]); const isMinIndex = useDerivedValue(() => curIndex <= minIndex, [curIndex, minIndex]); const isMaxIndex = useDerivedValue(() => curIndex >= maxIndex, [curIndex, maxIndex]); const initTouchX = useSharedValue(0); const initTouchY = useSharedValue(0); const startTranslate = useSharedValue(0); const handleBegin = e => { 'worklet'; startTranslate.value = translate.value; initTouchX.value = e.x; initTouchY.value = e.y; }; const handleTouchesMove = ({ changedTouches }, mgr) => { 'worklet'; const mainTouch = changedTouches[0]; const initialTouch = vertical ? initTouchY.value : initTouchX.value; const currentTouch = vertical ? mainTouch.y : mainTouch.x; const translateDelta = currentTouch - initialTouch; if (isMinIndex.value && translateDelta > 0 || isMaxIndex.value && translateDelta < 0) { mgr.fail(); } }; const handleUpdate = ({ translationX, translationY }) => { 'worklet'; const translation = vertical ? translationY : translationX; const crossAxisTranslation = vertical ? translationX : translationY; // Ignore gesture if swiping on the cross-axis if (Math.abs(crossAxisTranslation) > 10 && Math.abs(crossAxisTranslation) > Math.abs(translation)) { return; } const updatedTranslate = startTranslate.value + translation; const page = initialIndex + -updatedTranslate / viewSize.value; if (page >= minIndexAnim.value && page <= maxIndexAnim.value) { translate.value = updatedTranslate; } else { const boundary = page < minIndexAnim.value ? minIndexAnim.value : maxIndexAnim.value; const overflowPercentage = boundary - page; const clampedTranslation = updatedTranslate - overflowPercentage * viewSize.value; const bounceTranslation = overflowPercentage * viewSize.value; translate.value = clampedTranslation + bounceTranslation; } }; const handleEnd = ({ velocityX, velocityY, translationX, translationY }) => { 'worklet'; const velocity = vertical ? velocityY : velocityX; const translation = vertical ? translationY : translationX; const crossAxisTranslation = vertical ? translationX : translationY; // Ignore if swiping on the cross-axis if (Math.abs(crossAxisTranslation) > Math.abs(translation)) { return; } // Determine if it's a fling gesture const isFling = Math.abs(velocity) > 500; let velocityOffset = isFling ? viewSize.value / 2 : 0; if (velocity < 0) { velocityOffset *= -1; } let targetPage = initialIndex - Math.round((translate.value + velocityOffset) / viewSize.value); targetPage = Math.max(minIndexAnim.value, Math.min(maxIndexAnim.value, targetPage)); translate.value = withTiming(-(targetPage - initialIndex) * viewSize.value, { duration: 500, easing: Easing.bezier(0.25, 1, 0.5, 1) }); }; const panGesture = Gesture.Pan().onBegin(handleBegin).onTouchesMove(handleTouchesMove).onUpdate(handleUpdate).onEnd(handleEnd); return panGesture; }; //# sourceMappingURL=usePanGesture.js.map