react-native-full-calendars
Version:
React Native Full Calendar (RNFC) is an intuitive and powerful calendar component library designed for React Native.
112 lines (104 loc) • 4.14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.usePanGesture = void 0;
var _react = require("react");
var _reactNativeGestureHandler = require("react-native-gesture-handler");
var _reactNativeReanimated = require("react-native-reanimated");
var _store = require("../store");
const usePanGesture = ({
curIndex,
translate,
viewSize
}) => {
const {
props
} = (0, _react.useContext)(_store.SwiperContext);
const {
minIndex,
maxIndex,
vertical,
initialIndex
} = props;
// Derived values for animation boundaries
const minIndexAnim = (0, _reactNativeReanimated.useDerivedValue)(() => minIndex, [minIndex]);
const maxIndexAnim = (0, _reactNativeReanimated.useDerivedValue)(() => maxIndex, [maxIndex]);
const isMinIndex = (0, _reactNativeReanimated.useDerivedValue)(() => curIndex <= minIndex, [curIndex, minIndex]);
const isMaxIndex = (0, _reactNativeReanimated.useDerivedValue)(() => curIndex >= maxIndex, [curIndex, maxIndex]);
const initTouchX = (0, _reactNativeReanimated.useSharedValue)(0);
const initTouchY = (0, _reactNativeReanimated.useSharedValue)(0);
const startTranslate = (0, _reactNativeReanimated.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 = (0, _reactNativeReanimated.withTiming)(-(targetPage - initialIndex) * viewSize.value, {
duration: 500,
easing: _reactNativeReanimated.Easing.bezier(0.25, 1, 0.5, 1)
});
};
const panGesture = _reactNativeGestureHandler.Gesture.Pan().onBegin(handleBegin).onTouchesMove(handleTouchesMove).onUpdate(handleUpdate).onEnd(handleEnd);
return panGesture;
};
exports.usePanGesture = usePanGesture;
//# sourceMappingURL=usePanGesture.js.map