Skip to content

Commit

Permalink
Merge pull request #560 from dohooo/develop
Browse files Browse the repository at this point in the history
feat: add a new props `minScrollDistancePerSwipe`
  • Loading branch information
dohooo authored Mar 7, 2024
2 parents 29425ee + c181174 commit 35abd9f
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changeset/violet-buckets-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'react-native-reanimated-carousel': patch
---

Add a new props `minScrollDistancePerSwipe` to set the minimum scroll instance to make carousel scroll.

10 changes: 9 additions & 1 deletion example/website/pages/props.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
| ------ | ------- | -------- |
Expand Down
22 changes: 21 additions & 1 deletion src/components/ScrollViewGesture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
dataLength,
overscrollEnabled,
maxScrollDistancePerSwipe,
minScrollDistancePerSwipe,
fixedDirection,
},
} = React.useContext(CTX);
Expand All @@ -71,6 +72,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
const scrollEndVelocity = useSharedValue(0);
const containerRef = useAnimatedRef<Animated.View>();
const maxScrollDistancePerSwipeIsSet = typeof maxScrollDistancePerSwipe === "number";
const minScrollDistancePerSwipeIsSet = typeof minScrollDistancePerSwipe === "number";

// Get the limit of the scroll.
const getLimit = React.useCallback(() => {
Expand Down Expand Up @@ -351,10 +353,26 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (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);
}
Expand All @@ -373,6 +391,8 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
fixedDirection,
maxScrollDistancePerSwipeIsSet,
maxScrollDistancePerSwipe,
maxScrollDistancePerSwipeIsSet,
minScrollDistancePerSwipe,
endWithSpring,
withSpring,
onScrollEnd,
Expand Down
8 changes: 6 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,14 @@ export type TCarouselProps<T = any> = {
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.
Expand Down

0 comments on commit 35abd9f

Please sign in to comment.