From d3b683169cca9fba3083b52133758a7a39dcf25e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=9D=B1=E6=BE=94?= Date: Thu, 30 Sep 2021 16:38:07 +0800 Subject: [PATCH] fix: fix animation bug --- example/src/App.tsx | 7 +++++-- src/Carousel.tsx | 34 +++++++++++++++++----------------- src/useLock.ts | 2 +- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/example/src/App.tsx b/example/src/App.tsx index e8e4f0d5..99507a39 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -21,7 +21,8 @@ export default function App() { > - timingConfig={{ duration: 1000 }} + timingConfig={{ duration: 500 }} + autoPlayInterval={2000} ref={r} mode="parallax" width={width} @@ -58,7 +59,9 @@ export default function App() { alignItems: 'center', }} > - {index} + + {index} + diff --git a/src/Carousel.tsx b/src/Carousel.tsx index cd1d6361..66239127 100644 --- a/src/Carousel.tsx +++ b/src/Carousel.tsx @@ -188,7 +188,7 @@ function Carousel( ); const callComputedIndex = React.useCallback( - (isFinished: boolean) => isFinished && computedIndex?.(), + () => computedIndex?.(), [computedIndex] ); @@ -211,9 +211,10 @@ function Carousel( if (lockController.isLock()) return; ctx.startContentOffsetX = handlerOffsetX.value; ctx.currentContentOffsetX = handlerOffsetX.value; + ctx.start = true; }, onActive: (e, ctx: any) => { - if (lockController.isLock()) return; + if (lockController.isLock() || !ctx.start) return; /** * `onActive` and `onEnd` return different values of translationX!So that creates a bias!TAT * */ @@ -229,16 +230,15 @@ function Carousel( ); }, onEnd: (e, ctx: any) => { - if (lockController.isLock()) return; + if (lockController.isLock() || !ctx.start) return; const translationX = ctx.translationX; - function _withTimingCallback(num: number) { - lockController.lock(); return withTiming(num, timingConfig, (isFinished) => { if (isFinished) { + ctx.start = false; lockController.unLock(); + runOnJS(callComputedIndex)(); } - runOnJS(callComputedIndex)(isFinished); }); } @@ -249,7 +249,7 @@ function Carousel( if (!loop && handlerOffsetX.value >= 0) { return; } - + lockController.lock(); if ( Math.abs(translationX) + Math.abs(e.velocityX) > width / 2 @@ -275,7 +275,7 @@ function Carousel( ) { return; } - + lockController.lock(); if ( Math.abs(translationX) + Math.abs(e.velocityX) > width / 2 @@ -306,29 +306,29 @@ function Carousel( const Layouts = React.useMemo>(() => { switch (mode) { case 'parallax': - return ({ index, children }) => ( + return ({ index: i, children }) => ( {children} ); default: - return ({ index, children }) => ( + return ({ index: i, children }) => ( {children} @@ -360,10 +360,10 @@ function Carousel( style, ]} > - {data.map((item, index) => { + {data.map((item, i) => { return ( - - {renderItem(item, index)} + + {renderItem(item, i)} ); })} diff --git a/src/useLock.ts b/src/useLock.ts index 7c028e55..4c80dc15 100644 --- a/src/useLock.ts +++ b/src/useLock.ts @@ -1,5 +1,4 @@ import { useSharedValue } from 'react-native-reanimated'; - export interface ILockController { lock(): void; unLock(): void; @@ -10,6 +9,7 @@ export interface ILockController { * Cannot operate while animation is locking */ export function useLockController(): ILockController { + // This value is true if the animation is executing const _lock = useSharedValue(false); function lock() { 'worklet';