diff --git a/.changeset/violet-buckets-act.md b/.changeset/violet-buckets-act.md new file mode 100644 index 00000000..4d210f93 --- /dev/null +++ b/.changeset/violet-buckets-act.md @@ -0,0 +1,6 @@ +--- +'react-native-reanimated-carousel': patch +--- + +Add a new props `minScrollDistancePerSwipe` to set the minimum scroll instance to make carousel scroll. + diff --git a/example/website/pages/props.mdx b/example/website/pages/props.mdx index f4f4af77..39e00168 100644 --- a/example/website/pages/props.mdx +++ b/example/website/pages/props.mdx @@ -289,7 +289,15 @@ Custom animations. For details, see below\[custom animation\]\(.\/custom-animati ### `maxScrollDistancePerSwipe` -Maximum offset value for one scroll. If `props.vertical = true`, this will be `maxScrollDistancePerSwipeY`. If `props.vertical = false`, this will be `maxScrollDistancePerSwipeX`. +Maximum offset value for one scroll. Carousel cannot scroll over than this value. + +| type | default | required | +| ------ | ------- | -------- | +| number | - | ❌ | + +### `minScrollDistancePerSwipe` + +Minimum offset value for once scroll. If the translation value is less than this value, the carousel will not scroll. | type | default | required | | ------ | ------- | -------- | diff --git a/src/components/ScrollViewGesture.tsx b/src/components/ScrollViewGesture.tsx index 865bda8e..41e39b4b 100644 --- a/src/components/ScrollViewGesture.tsx +++ b/src/components/ScrollViewGesture.tsx @@ -46,6 +46,7 @@ const IScrollViewGesture: React.FC> = (props) => { dataLength, overscrollEnabled, maxScrollDistancePerSwipe, + minScrollDistancePerSwipe, fixedDirection, }, } = React.useContext(CTX); @@ -71,6 +72,7 @@ const IScrollViewGesture: React.FC> = (props) => { const scrollEndVelocity = useSharedValue(0); const containerRef = useAnimatedRef(); const maxScrollDistancePerSwipeIsSet = typeof maxScrollDistancePerSwipe === "number"; + const minScrollDistancePerSwipeIsSet = typeof minScrollDistancePerSwipe === "number"; // Get the limit of the scroll. const getLimit = React.useCallback(() => { @@ -351,10 +353,26 @@ const IScrollViewGesture: React.FC> = (props) => { const totalTranslation = scrollEndVelocity.value + scrollEndTranslation.value; - if (maxScrollDistancePerSwipeIsSet && Math.abs(totalTranslation) > maxScrollDistancePerSwipe) { + /** + * If the maximum scroll distance is set and the translation `exceeds the maximum scroll distance`, + * the carousel will keep the view at the current position. + */ + if ( + maxScrollDistancePerSwipeIsSet && Math.abs(totalTranslation) > maxScrollDistancePerSwipe + ) { const nextPage = Math.round((panOffset.value + maxScrollDistancePerSwipe * Math.sign(totalTranslation)) / size) * size; translation.value = withSpring(withProcessTranslation(nextPage), onScrollEnd); } + /** + * If the minimum scroll distance is set and the translation `didn't exceeds the minimum scroll distance`, + * the carousel will keep the view at the current position. + */ + else if ( + minScrollDistancePerSwipeIsSet && Math.abs(totalTranslation) < minScrollDistancePerSwipe + ) { + const nextPage = Math.round((panOffset.value + minScrollDistancePerSwipe * Math.sign(totalTranslation)) / size) * size; + translation.value = withSpring(withProcessTranslation(nextPage), onScrollEnd); + } else { endWithSpring(onScrollEnd); } @@ -373,6 +391,8 @@ const IScrollViewGesture: React.FC> = (props) => { fixedDirection, maxScrollDistancePerSwipeIsSet, maxScrollDistancePerSwipe, + maxScrollDistancePerSwipeIsSet, + minScrollDistancePerSwipe, endWithSpring, withSpring, onScrollEnd, diff --git a/src/types.ts b/src/types.ts index 9531b759..b8f99c70 100644 --- a/src/types.ts +++ b/src/types.ts @@ -153,10 +153,14 @@ export type TCarouselProps = { testID?: string /** * Maximum offset value for once scroll. - * props.vertical = true => maxScrollDistancePerSwipeY - * props.vertical = false => maxScrollDistancePerSwipeX + * Carousel cannot scroll over than this value. * */ maxScrollDistancePerSwipe?: number + /** + * Minimum offset value for once scroll. + * If the translation value is less than this value, the carousel will not scroll. + * */ + minScrollDistancePerSwipe?: number /** * @experimental This API will be changed in the future. * If positive, the carousel will scroll to the positive direction and vice versa.