Skip to content

Commit

Permalink
fix: drag issues occur when auto-scrolling
Browse files Browse the repository at this point in the history
fix #13
  • Loading branch information
gxxgcn committed Oct 27, 2021
1 parent 092b487 commit ebb0ce2
Show file tree
Hide file tree
Showing 4 changed files with 371 additions and 56 deletions.
3 changes: 1 addition & 2 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
/* eslint-disable react-native/no-inline-styles */
import * as React from 'react';
import { Dimensions, Image, ImageSourcePropType, View } from 'react-native';
import { ICarouselInstance } from '../../src/Carousel';

import Carousel from '../../src/index';
import type { ICarouselInstance } from '../../src/Carousel';

const { width } = Dimensions.get('window');

Expand Down
37 changes: 21 additions & 16 deletions src/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ function Carousel<T extends unknown = any>(
autoPlayInterval,
parallaxScrollingOffset,
parallaxScrollingScale,
onScrollBegin = () => {},
onSnapToItem,
style,
timingConfig = defaultTimingConfig,
Expand Down Expand Up @@ -175,14 +174,6 @@ function Carousel<T extends unknown = any>(
onChange: (i) => onSnapToItem && runOnJS(onSnapToItem)(i),
});

const { index, sharedPreIndex, sharedIndex, computedIndex } =
indexController;

const onScrollEnd = React.useCallback(() => {
computedIndex();
props.onScrollEnd?.(sharedPreIndex.current, sharedIndex.current);
}, [sharedPreIndex, sharedIndex, computedIndex, props]);

const carouselController = useCarouselController({
loop,
width,
Expand All @@ -195,19 +186,32 @@ function Carousel<T extends unknown = any>(
onScrollEnd: () => runOnJS(onScrollEnd)(),
});

const offsetX = useDerivedValue(() => {
const x = handlerOffsetX.value % computedAnimResult.WL;
return isNaN(x) ? 0 : x;
}, [computedAnimResult]);

useAutoPlay({
const { run, pause } = useAutoPlay({
autoPlay,
autoPlayInterval,
autoPlayReverse,
carouselController,
lockController,
});

const { index, sharedPreIndex, sharedIndex, computedIndex } =
indexController;

const onScrollBegin = React.useCallback(() => {
pause();
props.onScrollBegin?.();
}, [pause, props]);

const onScrollEnd = React.useCallback(() => {
run();
computedIndex();
props.onScrollEnd?.(sharedPreIndex.current, sharedIndex.current);
}, [sharedPreIndex, sharedIndex, computedIndex, props, run]);

const offsetX = useDerivedValue(() => {
const x = handlerOffsetX.value % computedAnimResult.WL;
return isNaN(x) ? 0 : x;
}, [computedAnimResult]);

const next = React.useCallback(() => {
return carouselController.next();
}, [carouselController]);
Expand All @@ -232,6 +236,7 @@ function Carousel<T extends unknown = any>(
{
onStart: (_, ctx: any) => {
if (lockController.isLock()) return;
runOnJS(pause)();
runOnJS(onScrollBegin)();
ctx.startContentOffsetX = handlerOffsetX.value;
ctx.currentContentOffsetX = handlerOffsetX.value;
Expand Down
33 changes: 18 additions & 15 deletions src/useAutoPlay.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,44 @@
import * as React from 'react';
import type { ICarouselController } from './useCarouselController';
import type { ILockController } from './useLock';

export function useAutoPlay(opts: {
autoPlay?: boolean;
autoPlayInterval?: number;
autoPlayReverse?: boolean;
carouselController: ICarouselController;
lockController: ILockController;
}) {
const {
autoPlay = false,
autoPlayReverse = false,
autoPlayInterval = 1000,
carouselController,
lockController,
} = opts;

const timer = React.useRef<NodeJS.Timer>();
React.useEffect(() => {
if (timer.current) {
clearInterval(timer.current);
}
if (autoPlay && !lockController.isLock()) {

const run = React.useCallback(() => {
if (autoPlay) {
timer.current = setInterval(() => {
autoPlayReverse
? carouselController.prev()
: carouselController.next();
}, autoPlayInterval);
}
}, [autoPlay, autoPlayReverse, carouselController, autoPlayInterval]);

const pause = React.useCallback(() => {
timer.current && clearInterval(timer.current);
}, []);

React.useEffect(() => {
run();
return () => {
!!timer.current && clearInterval(timer.current);
};
}, [
autoPlay,
autoPlayReverse,
autoPlayInterval,
carouselController,
lockController,
]);
}, [run, timer]);

return {
run,
pause,
};
}
Loading

0 comments on commit ebb0ce2

Please sign in to comment.