Skip to content

Commit

Permalink
feat: support pagingEnabled enableSnap
Browse files Browse the repository at this point in the history
  • Loading branch information
gxxgcn committed Jan 2, 2022
1 parent 0957502 commit 000658e
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 27 deletions.
8 changes: 5 additions & 3 deletions example/src/stack/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function Index() {
'left'
);
const [pagingEnabled, setPagingEnabled] = React.useState<boolean>(true);
const [snapToItem, setSnapToItem] = React.useState<boolean>(true);
const [enableSnap, setEnableSnap] = React.useState<boolean>(true);
const [loop, setLoop] = React.useState<boolean>(true);

const animationConfig = React.useMemo<StackAnimationConfig>(() => {
Expand Down Expand Up @@ -48,6 +48,8 @@ function Index() {
alignSelf: 'center',
justifyContent: 'center',
}}
pagingEnabled={pagingEnabled}
enableSnap={enableSnap}
mode="stack"
autoPlay
autoPlayInterval={2000}
Expand Down Expand Up @@ -90,10 +92,10 @@ function Index() {
</SButton>
<SButton
onPress={() => {
setSnapToItem(!snapToItem);
setEnableSnap(!enableSnap);
}}
>
{`snapToItem:${snapToItem}`}
{`enableSnap:${enableSnap}`}
</SButton>
</View>
);
Expand Down
5 changes: 4 additions & 1 deletion src/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ function Carousel<T>(
onSnapToItem,
onScrollBegin,
onProgressChange,
pagingEnabled = true,
enableSnap = true,
} = props;

let animationConfig: StackAnimationConfig | undefined;
Expand Down Expand Up @@ -273,7 +275,8 @@ function Carousel<T>(
return (
<View style={[styles.container, layoutStyle, style]}>
<ScrollViewGesture
pagingEnabled
pagingEnabled={pagingEnabled}
enableSnap={enableSnap}
vertical={vertical}
infinite={loop}
translation={handlerOffsetX}
Expand Down
60 changes: 37 additions & 23 deletions src/ScrollViewGesture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface Props {
style?: StyleProp<ViewStyle>;
infinite?: boolean;
pagingEnabled?: boolean;
enableSnap?: boolean;
vertical?: boolean;
panGestureHandlerProps?: Omit<
Partial<PanGestureHandlerProps>,
Expand All @@ -44,7 +45,8 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
infinite,
vertical,
translation,
pagingEnabled,
pagingEnabled = true,
enableSnap = true,
panGestureHandlerProps = {},
onScrollBegin,
onScrollEnd,
Expand All @@ -57,7 +59,7 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
const scrollEndTranslation = useSharedValue(0);
const scrollEndVelocity = useSharedValue(0);

const endWithSpring = React.useCallback(
const _withSpring = React.useCallback(
(toValue: number, onFinished?: () => void) => {
'worklet';
return withSpring(
Expand All @@ -75,9 +77,24 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
[]
);

const withPaging = React.useCallback(
const endWithSpring = React.useCallback(
(onFinished?: () => void) => {
'worklet';
const origin = translation.value;
const velocity = scrollEndVelocity.value;
if (!pagingEnabled) {
if (enableSnap) {
const nextPage =
Math.round((origin + velocity * 0.4) / size) * size;
translation.value = _withSpring(nextPage, onFinished);
return;
}
translation.value = withDecay({
velocity,
deceleration: 0.999,
});
return;
}
const page = Math.round(-translation.value / size);
const velocityPage = Math.round(
-(translation.value + scrollEndVelocity.value) / size
Expand All @@ -89,9 +106,19 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
if (!infinite) {
finalPage = Math.min(maxPage - 1, Math.max(0, finalPage));
}
translation.value = endWithSpring(-finalPage * size, onFinished);

translation.value = _withSpring(-finalPage * size, onFinished);
},
[infinite, endWithSpring, translation, scrollEndVelocity, size, maxPage]
[
infinite,
_withSpring,
translation,
scrollEndVelocity,
size,
maxPage,
pagingEnabled,
enableSnap,
]
);

const resetBoundary = React.useCallback(() => {
Expand Down Expand Up @@ -120,7 +147,7 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
return;
}
if (!infinite) {
translation.value = endWithSpring(0);
translation.value = _withSpring(0);
return;
}
}
Expand All @@ -131,14 +158,14 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
return;
}
if (!infinite) {
translation.value = endWithSpring(-((maxPage - 1) * size));
translation.value = _withSpring(-((maxPage - 1) * size));
return;
}
}
}, [
infinite,
touching,
endWithSpring,
_withSpring,
translation,
scrollEndTranslation,
scrollEndVelocity,
Expand Down Expand Up @@ -194,27 +221,14 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
? translationX
: translationY;

if (pagingEnabled) {
withPaging(() => onScrollEnd && runOnJS(onScrollEnd)());
return;
}
translation.value = withDecay(
{
velocity: scrollEndVelocity.value,
},
(isFinished) => {
if (isFinished) {
onScrollEnd && runOnJS(onScrollEnd)();
}
}
);
endWithSpring(() => onScrollEnd && runOnJS(onScrollEnd)());

if (!infinite) {
touching.value = false;
}
},
},
[pagingEnabled, isHorizontal.value, infinite, maxPage, size]
[pagingEnabled, isHorizontal.value, infinite, maxPage, size, enableSnap]
);

const directionStyle = React.useMemo(() => {
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ export type TCarouselProps<T = any> = {
* @default 0 all items will respond to pan gesture events.
*/
windowSize?: number;
pagingEnabled?: boolean;
enableSnap?: boolean;
/**
* Render carousel item.
*/
Expand Down

0 comments on commit 000658e

Please sign in to comment.