Skip to content

Commit

Permalink
fix: autoplay will scroll out of bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
dohooo committed Jan 11, 2022
1 parent 836f224 commit 2cfacff
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ function Carousel<T>(
onScrollEnd: () => runOnJS(_onScrollEnd)(),
onScrollBegin: () => !!onScrollBegin && runOnJS(onScrollBegin)(),
onChange: (i) => onSnapToItem && runOnJS(onSnapToItem)(i),
duration: autoPlayInterval,
});

const {
Expand Down
11 changes: 7 additions & 4 deletions src/ScrollViewGesture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import Animated, {
useDerivedValue,
useSharedValue,
withDecay,
withSpring,
withTiming,
} from 'react-native-reanimated';
import { Easing } from './constants';
import { CTX } from './store';

type GestureContext = {
Expand All @@ -40,6 +41,7 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
enableSnap,
panGestureHandlerProps,
loop: infinite,
autoPlayInterval,
},
} = React.useContext(CTX);

Expand All @@ -54,10 +56,11 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
const _withSpring = React.useCallback(
(toValue: number, onFinished?: () => void) => {
'worklet';
return withSpring(
return withTiming(
toValue,
{
damping: 100,
duration: autoPlayInterval,
easing: Easing.easeOutQuart,
},
(isFinished) => {
if (isFinished) {
Expand All @@ -66,7 +69,7 @@ const IScrollViewGesture: React.FC<Props> = (props) => {
}
);
},
[]
[autoPlayInterval]
);

const endWithSpring = React.useCallback(
Expand Down
6 changes: 6 additions & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { Easing as _Easing } from 'react-native-reanimated';

export enum DATA_LENGTH {
SINGLE_ITEM = 1,
DOUBLE_ITEM = 2,
}

export const Easing = {
easeOutQuart: _Easing.bezier(0.25, 1, 0.5, 1),
};
29 changes: 16 additions & 13 deletions src/hooks/useCarouselController.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import React from 'react';
import type Animated from 'react-native-reanimated';
import { runOnJS, useSharedValue, withSpring } from 'react-native-reanimated';
import { Easing } from '../constants';
import { runOnJS, useSharedValue, withTiming } from 'react-native-reanimated';

interface IOpts {
loop: boolean;
size: number;
handlerOffsetX: Animated.SharedValue<number>;
disable?: boolean;
duration?: number;
originalLength: number;
length: number;
onScrollBegin?: () => void;
onScrollEnd?: () => void;
// the length before fill data
originalLength: number;
length: number;
onChange: (index: number) => void;
}

Expand All @@ -36,6 +38,7 @@ export function useCarouselController(opts: IOpts): ICarouselController {
originalLength,
length,
onChange,
duration,
} = opts;

const index = useSharedValue<number>(0);
Expand Down Expand Up @@ -96,11 +99,11 @@ export function useCarouselController(opts: IOpts): ICarouselController {
opts.onScrollBegin?.();
}, [opts]);

const scrollWithSpring = React.useCallback(
const scrollWithTiming = React.useCallback(
(toValue: number, callback?: () => void) => {
return withSpring(
return withTiming(
toValue,
{ damping: 100 },
{ duration, easing: Easing.easeOutQuart },
(isFinished: boolean) => {
callback?.();
if (isFinished) {
Expand All @@ -109,7 +112,7 @@ export function useCarouselController(opts: IOpts): ICarouselController {
}
);
},
[onScrollEnd]
[onScrollEnd, duration]
);

const next = React.useCallback(() => {
Expand All @@ -119,7 +122,7 @@ export function useCarouselController(opts: IOpts): ICarouselController {

const currentPage = Math.round(handlerOffsetX.value / size);

handlerOffsetX.value = scrollWithSpring((currentPage - 1) * size);
handlerOffsetX.value = scrollWithTiming((currentPage - 1) * size);
}, [
canSliding,
loop,
Expand All @@ -128,7 +131,7 @@ export function useCarouselController(opts: IOpts): ICarouselController {
onScrollBegin,
handlerOffsetX,
size,
scrollWithSpring,
scrollWithTiming,
]);

const prev = React.useCallback(() => {
Expand All @@ -138,15 +141,15 @@ export function useCarouselController(opts: IOpts): ICarouselController {

const currentPage = Math.round(handlerOffsetX.value / size);

handlerOffsetX.value = scrollWithSpring((currentPage + 1) * size);
handlerOffsetX.value = scrollWithTiming((currentPage + 1) * size);
}, [
canSliding,
loop,
index.value,
onScrollBegin,
handlerOffsetX,
size,
scrollWithSpring,
scrollWithTiming,
]);

const to = React.useCallback(
Expand All @@ -159,7 +162,7 @@ export function useCarouselController(opts: IOpts): ICarouselController {
const offset = handlerOffsetX.value + (index.value - idx) * size;

if (animated) {
handlerOffsetX.value = scrollWithSpring(offset, () => {
handlerOffsetX.value = scrollWithTiming(offset, () => {
index.value = idx;
});
} else {
Expand All @@ -174,7 +177,7 @@ export function useCarouselController(opts: IOpts): ICarouselController {
onScrollBegin,
handlerOffsetX,
size,
scrollWithSpring,
scrollWithTiming,
onScrollEnd,
]
);
Expand Down

0 comments on commit 2cfacff

Please sign in to comment.