react-native-reanimated-carousel 5.1.1 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -1
- package/lib/commonjs/components/CarouselLayout.js +1 -1
- package/lib/commonjs/components/CarouselLayout.js.map +1 -1
- package/lib/commonjs/components/ItemLayout.js +1 -1
- package/lib/commonjs/components/ItemLayout.js.map +1 -1
- package/lib/commonjs/components/ItemRenderer.js +1 -1
- package/lib/commonjs/components/ItemRenderer.js.map +1 -1
- package/lib/commonjs/components/Pagination/PaginationItem.js +1 -1
- package/lib/commonjs/components/Pagination/PaginationItem.js.map +1 -1
- package/lib/commonjs/components/ScrollViewGesture.js +1 -1
- package/lib/commonjs/components/ScrollViewGesture.js.map +1 -1
- package/lib/commonjs/constants/index.js +1 -1
- package/lib/commonjs/constants/index.js.map +1 -1
- package/lib/commonjs/hooks/useAutoPlay.js +1 -1
- package/lib/commonjs/hooks/useAutoPlay.js.map +1 -1
- package/lib/commonjs/hooks/useCarouselController.js +1 -1
- package/lib/commonjs/hooks/useCarouselController.js.map +1 -1
- package/lib/commonjs/hooks/useCommonVariables.js +1 -1
- package/lib/commonjs/hooks/useCommonVariables.js.map +1 -1
- package/lib/commonjs/hooks/useInitProps.js +1 -1
- package/lib/commonjs/hooks/useInitProps.js.map +1 -1
- package/lib/commonjs/hooks/useOffsetX.js +1 -1
- package/lib/commonjs/hooks/useOffsetX.js.map +1 -1
- package/lib/commonjs/hooks/useOnProgressChange.js +1 -1
- package/lib/commonjs/hooks/useOnProgressChange.js.map +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.js +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -1
- package/lib/commonjs/layouts/normal.js +1 -1
- package/lib/commonjs/layouts/normal.js.map +1 -1
- package/lib/commonjs/layouts/parallax.js +1 -1
- package/lib/commonjs/layouts/parallax.js.map +1 -1
- package/lib/commonjs/utils/web-only-dependencies.js +2 -0
- package/lib/commonjs/utils/web-only-dependencies.js.map +1 -0
- package/lib/module/components/CarouselLayout.js +1 -1
- package/lib/module/components/CarouselLayout.js.map +1 -1
- package/lib/module/components/ItemLayout.js +1 -1
- package/lib/module/components/ItemLayout.js.map +1 -1
- package/lib/module/components/ItemRenderer.js +1 -1
- package/lib/module/components/ItemRenderer.js.map +1 -1
- package/lib/module/components/Pagination/PaginationItem.js +1 -1
- package/lib/module/components/Pagination/PaginationItem.js.map +1 -1
- package/lib/module/components/ScrollViewGesture.js +1 -1
- package/lib/module/components/ScrollViewGesture.js.map +1 -1
- package/lib/module/constants/index.js +1 -1
- package/lib/module/constants/index.js.map +1 -1
- package/lib/module/hooks/useAutoPlay.js +1 -1
- package/lib/module/hooks/useAutoPlay.js.map +1 -1
- package/lib/module/hooks/useCarouselController.js +1 -1
- package/lib/module/hooks/useCarouselController.js.map +1 -1
- package/lib/module/hooks/useCommonVariables.js +1 -1
- package/lib/module/hooks/useCommonVariables.js.map +1 -1
- package/lib/module/hooks/useInitProps.js +1 -1
- package/lib/module/hooks/useInitProps.js.map +1 -1
- package/lib/module/hooks/useOffsetX.js +1 -1
- package/lib/module/hooks/useOffsetX.js.map +1 -1
- package/lib/module/hooks/useOnProgressChange.js +1 -1
- package/lib/module/hooks/useOnProgressChange.js.map +1 -1
- package/lib/module/hooks/useVisibleRanges.js +1 -1
- package/lib/module/hooks/useVisibleRanges.js.map +1 -1
- package/lib/module/layouts/normal.js +1 -1
- package/lib/module/layouts/normal.js.map +1 -1
- package/lib/module/layouts/parallax.js +1 -1
- package/lib/module/layouts/parallax.js.map +1 -1
- package/lib/module/utils/web-only-dependencies.js +2 -0
- package/lib/module/utils/web-only-dependencies.js.map +1 -0
- package/lib/typescript/commonjs/components/CarouselLayout.d.ts.map +1 -1
- package/lib/typescript/commonjs/components/ItemLayout.d.ts.map +1 -1
- package/lib/typescript/commonjs/components/ItemRenderer.d.ts.map +1 -1
- package/lib/typescript/commonjs/components/Pagination/PaginationItem.d.ts.map +1 -1
- package/lib/typescript/commonjs/components/ScrollViewGesture.d.ts.map +1 -1
- package/lib/typescript/commonjs/constants/index.d.ts +4 -4
- package/lib/typescript/commonjs/constants/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/useAutoPlay.d.ts +19 -5
- package/lib/typescript/commonjs/hooks/useAutoPlay.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/useCarouselController.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/useCommonVariables.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/useInitProps.d.ts +2 -1
- package/lib/typescript/commonjs/hooks/useInitProps.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/useOffsetX.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/useOnProgressChange.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/usePanGestureProxy.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/useUpdateGestureConfig.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/useVisibleRanges.d.ts +1 -0
- package/lib/typescript/commonjs/hooks/useVisibleRanges.d.ts.map +1 -1
- package/lib/typescript/commonjs/layouts/normal.d.ts +2 -9
- package/lib/typescript/commonjs/layouts/normal.d.ts.map +1 -1
- package/lib/typescript/commonjs/layouts/parallax.d.ts +2 -16
- package/lib/typescript/commonjs/layouts/parallax.d.ts.map +1 -1
- package/lib/typescript/commonjs/layouts/stack.d.ts.map +1 -1
- package/lib/typescript/commonjs/public-types.d.ts +1 -0
- package/lib/typescript/commonjs/public-types.d.ts.map +1 -1
- package/lib/typescript/commonjs/store/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/utils/web-only-dependencies.d.ts +7 -0
- package/lib/typescript/commonjs/utils/web-only-dependencies.d.ts.map +1 -0
- package/lib/typescript/module/components/CarouselLayout.d.ts.map +1 -1
- package/lib/typescript/module/components/ItemLayout.d.ts.map +1 -1
- package/lib/typescript/module/components/ItemRenderer.d.ts.map +1 -1
- package/lib/typescript/module/components/Pagination/PaginationItem.d.ts.map +1 -1
- package/lib/typescript/module/components/ScrollViewGesture.d.ts.map +1 -1
- package/lib/typescript/module/constants/index.d.ts +4 -4
- package/lib/typescript/module/constants/index.d.ts.map +1 -1
- package/lib/typescript/module/hooks/useAutoPlay.d.ts +19 -5
- package/lib/typescript/module/hooks/useAutoPlay.d.ts.map +1 -1
- package/lib/typescript/module/hooks/useCarouselController.d.ts.map +1 -1
- package/lib/typescript/module/hooks/useCommonVariables.d.ts.map +1 -1
- package/lib/typescript/module/hooks/useInitProps.d.ts +2 -1
- package/lib/typescript/module/hooks/useInitProps.d.ts.map +1 -1
- package/lib/typescript/module/hooks/useOffsetX.d.ts.map +1 -1
- package/lib/typescript/module/hooks/useOnProgressChange.d.ts.map +1 -1
- package/lib/typescript/module/hooks/usePanGestureProxy.d.ts.map +1 -1
- package/lib/typescript/module/hooks/useUpdateGestureConfig.d.ts.map +1 -1
- package/lib/typescript/module/hooks/useVisibleRanges.d.ts +1 -0
- package/lib/typescript/module/hooks/useVisibleRanges.d.ts.map +1 -1
- package/lib/typescript/module/layouts/normal.d.ts +2 -9
- package/lib/typescript/module/layouts/normal.d.ts.map +1 -1
- package/lib/typescript/module/layouts/parallax.d.ts +2 -16
- package/lib/typescript/module/layouts/parallax.d.ts.map +1 -1
- package/lib/typescript/module/layouts/stack.d.ts.map +1 -1
- package/lib/typescript/module/public-types.d.ts +1 -0
- package/lib/typescript/module/public-types.d.ts.map +1 -1
- package/lib/typescript/module/store/index.d.ts.map +1 -1
- package/lib/typescript/module/utils/web-only-dependencies.d.ts +7 -0
- package/lib/typescript/module/utils/web-only-dependencies.d.ts.map +1 -0
- package/package.json +8 -4
- package/src/components/CarouselLayout.tsx +42 -12
- package/src/components/ItemLayout.tsx +14 -4
- package/src/components/ItemRenderer.tsx +36 -4
- package/src/components/Pagination/PaginationItem.tsx +22 -20
- package/src/components/ScrollViewGesture.tsx +12 -5
- package/src/constants/index.ts +4 -4
- package/src/hooks/useAutoPlay.ts +44 -17
- package/src/hooks/useCarouselController.tsx +3 -2
- package/src/hooks/useCommonVariables.ts +3 -2
- package/src/hooks/useInitProps.ts +13 -0
- package/src/hooks/useOffsetX.ts +11 -1
- package/src/hooks/useOnProgressChange.ts +2 -1
- package/src/hooks/useVisibleRanges.tsx +5 -2
- package/src/layouts/normal.ts +2 -1
- package/src/layouts/parallax.ts +2 -1
- package/src/public-types.ts +1 -0
- package/src/utils/web-only-dependencies.ts +10 -0
|
@@ -21,6 +21,7 @@ import { useGlobalState } from "../store";
|
|
|
21
21
|
import { toLogicalGestureValue } from "../utils/carousel-direction";
|
|
22
22
|
import { computeGestureTranslation } from "../utils/compute-gesture-translation";
|
|
23
23
|
import { dealWithAnimation } from "../utils/deal-with-animation";
|
|
24
|
+
import { webOnlyDependencies } from "../utils/web-only-dependencies";
|
|
24
25
|
|
|
25
26
|
interface Props {
|
|
26
27
|
size: number;
|
|
@@ -40,6 +41,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
40
41
|
onConfigurePanGesture,
|
|
41
42
|
orientation,
|
|
42
43
|
snapMode,
|
|
44
|
+
snapMomentum,
|
|
43
45
|
loop,
|
|
44
46
|
animation,
|
|
45
47
|
scrollEnabled,
|
|
@@ -63,7 +65,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
63
65
|
const isVertical = orientation === "vertical";
|
|
64
66
|
|
|
65
67
|
const maxPage = dataLength;
|
|
66
|
-
const isHorizontal = useDerivedValue(() => !isVertical, [isVertical]);
|
|
68
|
+
const isHorizontal = useDerivedValue(() => !isVertical, webOnlyDependencies([isVertical]));
|
|
67
69
|
const max = useSharedValue(0);
|
|
68
70
|
const panOffset = useSharedValue<number | undefined>(undefined); // set to undefined when not actively in a pan gesture
|
|
69
71
|
const touching = useSharedValue(false);
|
|
@@ -71,10 +73,11 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
71
73
|
const hasStartedMovement = useSharedValue(false);
|
|
72
74
|
const scrollEndTranslation = useSharedValue(0);
|
|
73
75
|
const scrollEndVelocity = useSharedValue(0);
|
|
76
|
+
const sizeReadyDependencies = webOnlyDependencies([resolvedSize, sizePhase]);
|
|
74
77
|
const sizeReady = useDerivedValue(() => {
|
|
75
78
|
const currentSize = resolvedSize.value ?? 0;
|
|
76
79
|
return sizePhase.value === "ready" && currentSize > 0;
|
|
77
|
-
},
|
|
80
|
+
}, sizeReadyDependencies);
|
|
78
81
|
|
|
79
82
|
// Get the limit of the scroll.
|
|
80
83
|
const getLimit = React.useCallback(() => {
|
|
@@ -169,7 +172,11 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
169
172
|
}
|
|
170
173
|
|
|
171
174
|
if (snapMode === "nearest") {
|
|
172
|
-
|
|
175
|
+
const nearestPage = -Math.round((origin + velocity * snapMomentum) / currentSize);
|
|
176
|
+
finalTranslation = withSpring(
|
|
177
|
+
withProcessTranslation(-nearestPage * currentSize),
|
|
178
|
+
onFinished
|
|
179
|
+
);
|
|
173
180
|
}
|
|
174
181
|
|
|
175
182
|
translation.value = finalTranslation;
|
|
@@ -183,7 +190,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
183
190
|
return translation;
|
|
184
191
|
}
|
|
185
192
|
},
|
|
186
|
-
[withSpring, resolvedSize, maxPage, loop, snapMode, translation]
|
|
193
|
+
[withSpring, resolvedSize, maxPage, loop, snapMode, snapMomentum, translation]
|
|
187
194
|
);
|
|
188
195
|
|
|
189
196
|
const onFinish = React.useCallback(
|
|
@@ -238,7 +245,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
238
245
|
() => {
|
|
239
246
|
if (snapMode !== "page") resetBoundary();
|
|
240
247
|
},
|
|
241
|
-
[resetBoundary, snapMode]
|
|
248
|
+
webOnlyDependencies([resetBoundary, snapMode])
|
|
242
249
|
);
|
|
243
250
|
|
|
244
251
|
const onGestureStart = useCallback(
|
package/src/constants/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { EasingFunction } from "react-native-reanimated";
|
|
2
2
|
import { Easing as _Easing } from "react-native-reanimated";
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
SINGLE_ITEM
|
|
6
|
-
DOUBLE_ITEM
|
|
7
|
-
}
|
|
4
|
+
export const DATA_LENGTH = {
|
|
5
|
+
SINGLE_ITEM: 1,
|
|
6
|
+
DOUBLE_ITEM: 2,
|
|
7
|
+
} as const;
|
|
8
8
|
|
|
9
9
|
export const Easing = {
|
|
10
10
|
easeOutQuart: _Easing.bezier(0.25, 1, 0.5, 1) as unknown as EasingFunction,
|
package/src/hooks/useAutoPlay.ts
CHANGED
|
@@ -2,12 +2,31 @@ import * as React from "react";
|
|
|
2
2
|
|
|
3
3
|
import type { CarouselController } from "./useCarouselController";
|
|
4
4
|
|
|
5
|
+
export interface AutoPlayControls {
|
|
6
|
+
/** Stops autoplay until `start` is called, for example while the user touches the carousel. */
|
|
7
|
+
pause: () => void;
|
|
8
|
+
/** Resumes autoplay and begins a fresh dwell. */
|
|
9
|
+
start: () => void;
|
|
10
|
+
/** Begins a fresh dwell if autoplay is running. */
|
|
11
|
+
trigger: () => void;
|
|
12
|
+
/** A transition started from any source: drop the pending dwell without stopping autoplay. */
|
|
13
|
+
onTransitionStart: () => void;
|
|
14
|
+
/** A transition settled from any source: begin a fresh dwell if autoplay is running. */
|
|
15
|
+
onTransitionEnd: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Autoplay waits `autoplayInterval` of idle time, then steps once. The dwell is restarted
|
|
20
|
+
* when a transition settles, whatever started it (an autoplay step, `ref.next/prev/scrollTo`,
|
|
21
|
+
* or a pagination tap), so a manual move never cuts the next dwell short and an interrupted
|
|
22
|
+
* autoplay step does not stop autoplay.
|
|
23
|
+
*/
|
|
5
24
|
export function useAutoPlay(options: {
|
|
6
25
|
autoplay?: boolean;
|
|
7
26
|
autoplayInterval?: number;
|
|
8
27
|
autoplayDirection?: "forward" | "backward";
|
|
9
28
|
carouselController: CarouselController;
|
|
10
|
-
}) {
|
|
29
|
+
}): AutoPlayControls {
|
|
11
30
|
const {
|
|
12
31
|
autoplay = false,
|
|
13
32
|
autoplayDirection = "forward",
|
|
@@ -18,28 +37,31 @@ export function useAutoPlay(options: {
|
|
|
18
37
|
const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
19
38
|
const stopped = React.useRef(!autoplay);
|
|
20
39
|
|
|
21
|
-
const
|
|
22
|
-
if (stopped.current) return;
|
|
23
|
-
|
|
40
|
+
const clearDwell = React.useCallback(() => {
|
|
24
41
|
if (timer.current) {
|
|
25
42
|
clearTimeout(timer.current);
|
|
26
43
|
timer.current = null;
|
|
27
44
|
}
|
|
45
|
+
}, []);
|
|
46
|
+
|
|
47
|
+
const play = React.useCallback(() => {
|
|
48
|
+
if (stopped.current) return;
|
|
49
|
+
|
|
50
|
+
clearDwell();
|
|
28
51
|
timer.current = setTimeout(() => {
|
|
29
|
-
|
|
30
|
-
|
|
52
|
+
timer.current = null;
|
|
53
|
+
// The step settles through `onTransitionEnd`, which starts the next dwell.
|
|
54
|
+
if (autoplayDirection === "backward") prev();
|
|
55
|
+
else next();
|
|
31
56
|
}, autoplayInterval);
|
|
32
|
-
}, [autoplayDirection, autoplayInterval, next, prev]);
|
|
57
|
+
}, [autoplayDirection, autoplayInterval, clearDwell, next, prev]);
|
|
33
58
|
|
|
34
59
|
const pause = React.useCallback(() => {
|
|
35
60
|
if (!autoplay) return;
|
|
36
61
|
|
|
37
|
-
|
|
38
|
-
clearTimeout(timer.current);
|
|
39
|
-
timer.current = null;
|
|
40
|
-
}
|
|
62
|
+
clearDwell();
|
|
41
63
|
stopped.current = true;
|
|
42
|
-
}, [autoplay]);
|
|
64
|
+
}, [autoplay, clearDwell]);
|
|
43
65
|
|
|
44
66
|
const start = React.useCallback(() => {
|
|
45
67
|
if (!autoplay) return;
|
|
@@ -55,9 +77,14 @@ export function useAutoPlay(options: {
|
|
|
55
77
|
return pause;
|
|
56
78
|
}, [autoplay, pause, start]);
|
|
57
79
|
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
80
|
+
return React.useMemo(
|
|
81
|
+
() => ({
|
|
82
|
+
pause,
|
|
83
|
+
start,
|
|
84
|
+
trigger: play,
|
|
85
|
+
onTransitionStart: clearDwell,
|
|
86
|
+
onTransitionEnd: play,
|
|
87
|
+
}),
|
|
88
|
+
[clearDwell, pause, play, start]
|
|
89
|
+
);
|
|
63
90
|
}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
positiveModulo,
|
|
19
19
|
} from "../utils/carousel-math";
|
|
20
20
|
import { dealWithAnimation } from "../utils/deal-with-animation";
|
|
21
|
+
import { webOnlyDependencies } from "../utils/web-only-dependencies";
|
|
21
22
|
|
|
22
23
|
interface CarouselControllerOptions {
|
|
23
24
|
ref: React.ForwardedRef<CarouselRef>;
|
|
@@ -71,7 +72,7 @@ export function useCarouselController(options: CarouselControllerOptions): Carou
|
|
|
71
72
|
const liveRawIndex = useRef(rawDataLength > 0 ? defaultIndex : 0);
|
|
72
73
|
const settledIndex = useRef(rawDataLength > 0 ? defaultIndex : 0);
|
|
73
74
|
const warnedCommands = useRef(new Set<string>());
|
|
74
|
-
const canMove = rawDataLength > 1;
|
|
75
|
+
const canMove = rawDataLength > 1 || (loop && rawDataLength === 1 && dataLength > 1);
|
|
75
76
|
|
|
76
77
|
const warnOnce = React.useCallback((key: string, message: string) => {
|
|
77
78
|
if (!__DEV__ || warnedCommands.current.has(key)) return;
|
|
@@ -106,7 +107,7 @@ export function useCarouselController(options: CarouselControllerOptions): Carou
|
|
|
106
107
|
index.value = physicalIndex;
|
|
107
108
|
scheduleOnRN(setLiveRawIndex, rawIndex);
|
|
108
109
|
},
|
|
109
|
-
[dataLength, handlerOffset, index, rawDataLength, size]
|
|
110
|
+
webOnlyDependencies([dataLength, handlerOffset, index, rawDataLength, size])
|
|
110
111
|
);
|
|
111
112
|
|
|
112
113
|
const settle = React.useCallback(
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
reconcileOffsetAfterDataChange,
|
|
13
13
|
} from "../utils/carousel-math";
|
|
14
14
|
import { computeOffsetIfSizeChanged } from "../utils/compute-offset-if-size-changed";
|
|
15
|
+
import { webOnlyDependencies } from "../utils/web-only-dependencies";
|
|
15
16
|
|
|
16
17
|
export type CarouselSizePhase = "pending" | "ready" | "updating";
|
|
17
18
|
|
|
@@ -97,7 +98,7 @@ export function useCommonVariables(
|
|
|
97
98
|
scheduleOnRN(syncSize, current);
|
|
98
99
|
}
|
|
99
100
|
},
|
|
100
|
-
[syncSize]
|
|
101
|
+
webOnlyDependencies([syncSize])
|
|
101
102
|
);
|
|
102
103
|
|
|
103
104
|
React.useEffect(() => {
|
|
@@ -242,7 +243,7 @@ export function useCommonVariables(
|
|
|
242
243
|
prevSize.value = currentSize;
|
|
243
244
|
sizePhase.value = "ready";
|
|
244
245
|
},
|
|
245
|
-
[dataLength, defaultIndex, hasInitializedOffset, resolvedSize, sizePhase]
|
|
246
|
+
webOnlyDependencies([dataLength, defaultIndex, hasInitializedOffset, resolvedSize, sizePhase])
|
|
246
247
|
);
|
|
247
248
|
|
|
248
249
|
return {
|
|
@@ -20,6 +20,7 @@ export type InitializedCarouselProps<Item> = Omit<
|
|
|
20
20
|
| "overscrollEnabled"
|
|
21
21
|
| "scrollEnabled"
|
|
22
22
|
| "snapMode"
|
|
23
|
+
| "snapMomentum"
|
|
23
24
|
| "style"
|
|
24
25
|
> & {
|
|
25
26
|
autoplay: boolean;
|
|
@@ -32,6 +33,7 @@ export type InitializedCarouselProps<Item> = Omit<
|
|
|
32
33
|
overscrollEnabled: boolean;
|
|
33
34
|
scrollEnabled: boolean;
|
|
34
35
|
snapMode: CarouselSnapMode;
|
|
36
|
+
snapMomentum: number;
|
|
35
37
|
style: NonNullable<CarouselProps<Item>["style"]>;
|
|
36
38
|
animation: CarouselAnimation;
|
|
37
39
|
rawData: Item[];
|
|
@@ -57,6 +59,7 @@ export function useInitProps<Item>(props: CarouselProps<Item>): InitializedCarou
|
|
|
57
59
|
});
|
|
58
60
|
const scrollEnabled = props.scrollEnabled ?? true;
|
|
59
61
|
const snapMode = props.snapMode ?? "page";
|
|
62
|
+
const snapMomentum = props.snapMomentum ?? 2;
|
|
60
63
|
const overscrollEnabled = props.overscrollEnabled ?? true;
|
|
61
64
|
const style = props.style ?? {};
|
|
62
65
|
const animation: CarouselAnimation = props.animation ?? {
|
|
@@ -123,6 +126,7 @@ export function useInitProps<Item>(props: CarouselProps<Item>): InitializedCarou
|
|
|
123
126
|
overscrollEnabled,
|
|
124
127
|
scrollEnabled,
|
|
125
128
|
snapMode,
|
|
129
|
+
snapMomentum,
|
|
126
130
|
style,
|
|
127
131
|
animation,
|
|
128
132
|
data,
|
|
@@ -154,6 +158,15 @@ function validateStaticProps<Item>(props: CarouselProps<Item>) {
|
|
|
154
158
|
);
|
|
155
159
|
}
|
|
156
160
|
|
|
161
|
+
if (
|
|
162
|
+
props.snapMomentum !== undefined &&
|
|
163
|
+
(!Number.isFinite(props.snapMomentum) || props.snapMomentum < 0)
|
|
164
|
+
) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
"[react-native-reanimated-carousel] snapMomentum must be a non-negative number."
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
157
170
|
if (
|
|
158
171
|
props.renderWindowSize !== undefined &&
|
|
159
172
|
(!Number.isInteger(props.renderWindowSize) || props.renderWindowSize <= 0)
|
package/src/hooks/useOffsetX.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SharedValue } from "react-native-reanimated";
|
|
2
2
|
import { Extrapolation, interpolate, useDerivedValue } from "react-native-reanimated";
|
|
3
3
|
|
|
4
|
+
import { webOnlyDependencies } from "../utils/web-only-dependencies";
|
|
4
5
|
import type { VisibleRangesValue } from "./useVisibleRanges";
|
|
5
6
|
|
|
6
7
|
export interface OffsetOptions {
|
|
@@ -38,6 +39,15 @@ export const useOffsetX = (opts: OffsetOptions, visibleRanges: VisibleRangesValu
|
|
|
38
39
|
const MAX = positiveCount * size;
|
|
39
40
|
const MIN = -((VALID_LENGTH - positiveCount) * size);
|
|
40
41
|
|
|
42
|
+
const xDependencies = webOnlyDependencies([
|
|
43
|
+
loop,
|
|
44
|
+
dataLength,
|
|
45
|
+
viewCount,
|
|
46
|
+
type,
|
|
47
|
+
size,
|
|
48
|
+
visibleRanges,
|
|
49
|
+
handlerOffset,
|
|
50
|
+
]);
|
|
41
51
|
const x = useDerivedValue(() => {
|
|
42
52
|
if (!size) return 0;
|
|
43
53
|
|
|
@@ -75,7 +85,7 @@ export const useOffsetX = (opts: OffsetOptions, visibleRanges: VisibleRangesValu
|
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
return Number.MAX_SAFE_INTEGER;
|
|
78
|
-
},
|
|
88
|
+
}, xDependencies);
|
|
79
89
|
|
|
80
90
|
return x;
|
|
81
91
|
};
|
|
@@ -4,6 +4,7 @@ import { scheduleOnRN } from "react-native-worklets";
|
|
|
4
4
|
|
|
5
5
|
import type { CarouselProgressChangeHandler } from "../types";
|
|
6
6
|
import { getLogicalProgress } from "../utils/carousel-math";
|
|
7
|
+
import { webOnlyDependencies } from "../utils/web-only-dependencies";
|
|
7
8
|
|
|
8
9
|
export function useOnProgressChange(options: {
|
|
9
10
|
loop: boolean;
|
|
@@ -28,6 +29,6 @@ export function useOnProgressChange(options: {
|
|
|
28
29
|
if (progress) progress.value = nextProgress;
|
|
29
30
|
if (onProgressChange) scheduleOnRN(onProgressChange, nextProgress);
|
|
30
31
|
},
|
|
31
|
-
[loop, offset, onProgressChange, progress, rawDataLength, size, sizeReady]
|
|
32
|
+
webOnlyDependencies([loop, offset, onProgressChange, progress, rawDataLength, size, sizeReady])
|
|
32
33
|
);
|
|
33
34
|
}
|
|
@@ -2,6 +2,8 @@ import { useRef } from "react";
|
|
|
2
2
|
import type { SharedValue } from "react-native-reanimated";
|
|
3
3
|
import { useDerivedValue } from "react-native-reanimated";
|
|
4
4
|
|
|
5
|
+
import { webOnlyDependencies } from "../utils/web-only-dependencies";
|
|
6
|
+
|
|
5
7
|
type Range = [number, number];
|
|
6
8
|
|
|
7
9
|
export interface VisibleRanges {
|
|
@@ -11,7 +13,7 @@ export interface VisibleRanges {
|
|
|
11
13
|
|
|
12
14
|
export type VisibleRangesValue = SharedValue<VisibleRanges>;
|
|
13
15
|
|
|
14
|
-
function normalizeWindowSize(total: number, windowSize?: number) {
|
|
16
|
+
export function normalizeWindowSize(total: number, windowSize?: number) {
|
|
15
17
|
"worklet";
|
|
16
18
|
|
|
17
19
|
return typeof windowSize === "number" && Number.isFinite(windowSize) && windowSize > 0
|
|
@@ -100,6 +102,7 @@ export function useVisibleRanges(options: {
|
|
|
100
102
|
const windowSize = normalizeWindowSize(total, _windowSize);
|
|
101
103
|
const cachedRanges = useRef<VisibleRanges | null>(null);
|
|
102
104
|
|
|
105
|
+
const rangesDependencies = webOnlyDependencies([loop, total, windowSize, translation, viewSize]);
|
|
103
106
|
const ranges = useDerivedValue(() => {
|
|
104
107
|
if (total <= 0) {
|
|
105
108
|
return computeVisibleRanges({ total, currentIndex: 0, windowSize, loop });
|
|
@@ -128,7 +131,7 @@ export function useVisibleRanges(options: {
|
|
|
128
131
|
|
|
129
132
|
cachedRanges.current = newRanges;
|
|
130
133
|
return newRanges;
|
|
131
|
-
},
|
|
134
|
+
}, rangesDependencies);
|
|
132
135
|
|
|
133
136
|
return ranges;
|
|
134
137
|
}
|
package/src/layouts/normal.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ViewStyle } from "react-native";
|
|
1
2
|
import { interpolate } from "react-native-reanimated";
|
|
2
3
|
|
|
3
4
|
import type { CarouselDirectionSign } from "../utils/carousel-direction";
|
|
@@ -10,7 +11,7 @@ export function normalLayout(opts: {
|
|
|
10
11
|
}) {
|
|
11
12
|
const { size, isVertical, directionSign } = opts;
|
|
12
13
|
|
|
13
|
-
return (value: number) => {
|
|
14
|
+
return (value: number): ViewStyle => {
|
|
14
15
|
"worklet";
|
|
15
16
|
const logicalTranslate = interpolate(value, [-1, 0, 1], [-size, 0, size]);
|
|
16
17
|
const translate = isVertical
|
package/src/layouts/parallax.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ViewStyle } from "react-native";
|
|
1
2
|
import { Extrapolation, interpolate } from "react-native-reanimated";
|
|
2
3
|
|
|
3
4
|
import type { CarouselLayout } from "../types";
|
|
@@ -17,7 +18,7 @@ export function parallaxLayout(
|
|
|
17
18
|
const { size, isVertical, directionSign } = baseConfig;
|
|
18
19
|
const { offset = 100, scale = 0.8, adjacentScale = scale ** 2 } = config;
|
|
19
20
|
|
|
20
|
-
return (relativeProgress: number) => {
|
|
21
|
+
return (relativeProgress: number): ViewStyle => {
|
|
21
22
|
"worklet";
|
|
22
23
|
const logicalTranslate = interpolate(
|
|
23
24
|
relativeProgress,
|
package/src/public-types.ts
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Platform } from "react-native";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Reanimated only reads hook dependency arrays in its Web implementation when the
|
|
5
|
+
* worklets Babel plugin is not used. Native derives them from the worklet closure
|
|
6
|
+
* and, since Reanimated 4.6, warns on every render when an array is passed.
|
|
7
|
+
*/
|
|
8
|
+
export function webOnlyDependencies<T extends unknown[]>(dependencies: T): T | undefined {
|
|
9
|
+
return Platform.OS === "web" ? dependencies : undefined;
|
|
10
|
+
}
|