react-native-reanimated-carousel 4.0.0-alpha.5 → 4.0.0-alpha.7
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/lib/commonjs/{layouts → components}/BaseLayout.js +4 -2
- package/lib/commonjs/components/BaseLayout.js.map +1 -0
- package/lib/commonjs/components/Carousel.js +8 -5
- package/lib/commonjs/components/Carousel.js.map +1 -1
- package/lib/commonjs/components/ScrollViewGesture.js +34 -30
- package/lib/commonjs/components/ScrollViewGesture.js.map +1 -1
- package/lib/commonjs/hooks/useCarouselController.js +4 -3
- package/lib/commonjs/hooks/useCarouselController.js.map +1 -1
- package/lib/commonjs/hooks/useLayoutConfig.js.map +1 -1
- package/lib/commonjs/hooks/useOffsetX.js +9 -6
- package/lib/commonjs/hooks/useOffsetX.js.map +1 -1
- package/lib/commonjs/hooks/useOffsetX.test.js +53 -0
- package/lib/commonjs/hooks/useOffsetX.test.js.map +1 -0
- package/lib/commonjs/hooks/usePanGestureProxy.js +84 -0
- package/lib/commonjs/hooks/usePanGestureProxy.js.map +1 -0
- package/lib/commonjs/hooks/usePanGestureProxy.test.js +397 -0
- package/lib/commonjs/hooks/usePanGestureProxy.test.js.map +1 -0
- package/lib/commonjs/hooks/useUpdateGestureConfig.js.map +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.js +20 -8
- package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.test.js +162 -0
- package/lib/commonjs/hooks/useVisibleRanges.test.js.map +1 -0
- package/lib/commonjs/utils/handleroffset-direction.js +5 -5
- package/lib/commonjs/utils/handleroffset-direction.js.map +1 -1
- package/lib/commonjs/utils/handleroffset-direction.test.js +46 -0
- package/lib/commonjs/utils/handleroffset-direction.test.js.map +1 -0
- package/lib/module/{layouts → components}/BaseLayout.js +4 -2
- package/lib/module/components/BaseLayout.js.map +1 -0
- package/lib/module/components/Carousel.js +7 -4
- package/lib/module/components/Carousel.js.map +1 -1
- package/lib/module/components/ScrollViewGesture.js +36 -31
- package/lib/module/components/ScrollViewGesture.js.map +1 -1
- package/lib/module/hooks/useCarouselController.js +4 -3
- package/lib/module/hooks/useCarouselController.js.map +1 -1
- package/lib/module/hooks/useLayoutConfig.js.map +1 -1
- package/lib/module/hooks/useOffsetX.js +9 -6
- package/lib/module/hooks/useOffsetX.js.map +1 -1
- package/lib/module/hooks/useOffsetX.test.js +48 -0
- package/lib/module/hooks/useOffsetX.test.js.map +1 -0
- package/lib/module/hooks/usePanGestureProxy.js +71 -0
- package/lib/module/hooks/usePanGestureProxy.js.map +1 -0
- package/lib/module/hooks/usePanGestureProxy.test.js +383 -0
- package/lib/module/hooks/usePanGestureProxy.test.js.map +1 -0
- package/lib/module/hooks/useUpdateGestureConfig.js.map +1 -1
- package/lib/module/hooks/useVisibleRanges.js +20 -8
- package/lib/module/hooks/useVisibleRanges.js.map +1 -1
- package/lib/module/hooks/useVisibleRanges.test.js +157 -0
- package/lib/module/hooks/useVisibleRanges.test.js.map +1 -0
- package/lib/module/utils/handleroffset-direction.js +5 -5
- package/lib/module/utils/handleroffset-direction.js.map +1 -1
- package/lib/module/utils/handleroffset-direction.test.js +41 -0
- package/lib/module/utils/handleroffset-direction.test.js.map +1 -0
- package/lib/typescript/hooks/useCarouselController.d.ts +2 -1
- package/lib/typescript/hooks/useLayoutConfig.d.ts +1 -1
- package/lib/typescript/hooks/useOffsetX.test.d.ts +1 -0
- package/lib/typescript/hooks/usePanGestureProxy.d.ts +9 -0
- package/lib/typescript/hooks/usePanGestureProxy.test.d.ts +1 -0
- package/lib/typescript/hooks/useUpdateGestureConfig.d.ts +3 -2
- package/lib/typescript/hooks/useVisibleRanges.d.ts +1 -0
- package/lib/typescript/hooks/useVisibleRanges.test.d.ts +1 -0
- package/lib/typescript/types.d.ts +5 -0
- package/lib/typescript/utils/handleroffset-direction.d.ts +2 -1
- package/lib/typescript/utils/handleroffset-direction.test.d.ts +1 -0
- package/package.json +2 -1
- package/src/{layouts → components}/BaseLayout.tsx +10 -8
- package/src/components/Carousel.tsx +5 -2
- package/src/components/ScrollViewGesture.tsx +48 -43
- package/src/hooks/useCarouselController.tsx +16 -13
- package/src/hooks/useLayoutConfig.ts +1 -1
- package/src/hooks/useOffsetX.test.ts +54 -0
- package/src/hooks/useOffsetX.ts +33 -31
- package/src/hooks/usePanGestureProxy.test.tsx +377 -0
- package/src/hooks/usePanGestureProxy.ts +110 -0
- package/src/hooks/useUpdateGestureConfig.ts +4 -2
- package/src/hooks/useVisibleRanges.test.tsx +179 -0
- package/src/hooks/useVisibleRanges.tsx +25 -9
- package/src/types.ts +5 -0
- package/src/utils/handleroffset-direction.test.ts +52 -0
- package/src/utils/handleroffset-direction.ts +12 -9
- package/lib/commonjs/layouts/BaseLayout.js.map +0 -1
- package/lib/commonjs/layouts/ParallaxLayout.js +0 -84
- package/lib/commonjs/layouts/ParallaxLayout.js.map +0 -1
- package/lib/module/layouts/BaseLayout.js.map +0 -1
- package/lib/module/layouts/ParallaxLayout.js +0 -61
- package/lib/module/layouts/ParallaxLayout.js.map +0 -1
- package/lib/typescript/layouts/ParallaxLayout.d.ts +0 -13
- package/src/layouts/ParallaxLayout.tsx +0 -141
- /package/lib/typescript/{layouts → components}/BaseLayout.d.ts +0 -0
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import type { PropsWithChildren } from "react";
|
|
2
|
-
import React, { useCallback
|
|
2
|
+
import React, { useCallback } from "react";
|
|
3
3
|
import type { StyleProp, ViewStyle } from "react-native";
|
|
4
4
|
import type { GestureStateChangeEvent, PanGestureHandlerEventPayload } from "react-native-gesture-handler";
|
|
5
|
-
import {
|
|
6
|
-
Gesture,
|
|
7
|
-
GestureDetector,
|
|
8
|
-
} from "react-native-gesture-handler";
|
|
5
|
+
import { GestureDetector } from "react-native-gesture-handler";
|
|
9
6
|
import Animated, {
|
|
10
7
|
cancelAnimation,
|
|
11
8
|
measure,
|
|
@@ -18,7 +15,7 @@ import Animated, {
|
|
|
18
15
|
} from "react-native-reanimated";
|
|
19
16
|
|
|
20
17
|
import { Easing } from "../constants";
|
|
21
|
-
import {
|
|
18
|
+
import { usePanGestureProxy } from "../hooks/usePanGestureProxy";
|
|
22
19
|
import { CTX } from "../store";
|
|
23
20
|
import type { WithTimingAnimation } from "../types";
|
|
24
21
|
import { dealWithAnimation } from "../utils/deal-with-animation";
|
|
@@ -42,13 +39,14 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
42
39
|
vertical,
|
|
43
40
|
pagingEnabled,
|
|
44
41
|
snapEnabled,
|
|
45
|
-
loop
|
|
42
|
+
loop,
|
|
46
43
|
scrollAnimationDuration,
|
|
47
44
|
withAnimation,
|
|
48
45
|
enabled,
|
|
49
46
|
dataLength,
|
|
50
47
|
overscrollEnabled,
|
|
51
48
|
maxScrollDistancePerSwipe,
|
|
49
|
+
fixedDirection,
|
|
52
50
|
},
|
|
53
51
|
} = React.useContext(CTX);
|
|
54
52
|
|
|
@@ -78,7 +76,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
78
76
|
const getLimit = React.useCallback(() => {
|
|
79
77
|
"worklet";
|
|
80
78
|
|
|
81
|
-
if (!
|
|
79
|
+
if (!loop && !overscrollEnabled) {
|
|
82
80
|
const { width: containerWidth = 0 } = measure(containerRef);
|
|
83
81
|
|
|
84
82
|
// If the item's total width is less than the container's width, then there is no need to scroll.
|
|
@@ -90,7 +88,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
90
88
|
}
|
|
91
89
|
|
|
92
90
|
return dataLength * size;
|
|
93
|
-
}, [
|
|
91
|
+
}, [loop, size, dataLength, overscrollEnabled]);
|
|
94
92
|
|
|
95
93
|
const withSpring = React.useCallback(
|
|
96
94
|
(toValue: number, onFinished?: () => void) => {
|
|
@@ -141,7 +139,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
141
139
|
const computed = offset < 0 ? Math.ceil : Math.floor;
|
|
142
140
|
const page = computed(-translation.value / size);
|
|
143
141
|
|
|
144
|
-
if (
|
|
142
|
+
if (loop) {
|
|
145
143
|
const finalPage = page + offset;
|
|
146
144
|
finalTranslation = withSpring(withProcessTranslation(-finalPage * size), onFinished);
|
|
147
145
|
}
|
|
@@ -161,7 +159,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
161
159
|
translation.value = finalTranslation;
|
|
162
160
|
|
|
163
161
|
function withProcessTranslation(translation: number) {
|
|
164
|
-
if (!
|
|
162
|
+
if (!loop && !overscrollEnabled) {
|
|
165
163
|
const limit = getLimit();
|
|
166
164
|
const sign = Math.sign(translation);
|
|
167
165
|
return sign * Math.max(0, Math.min(limit, Math.abs(translation)));
|
|
@@ -174,7 +172,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
174
172
|
withSpring,
|
|
175
173
|
size,
|
|
176
174
|
maxPage,
|
|
177
|
-
|
|
175
|
+
loop,
|
|
178
176
|
snapEnabled,
|
|
179
177
|
translation,
|
|
180
178
|
pagingEnabled,
|
|
@@ -215,7 +213,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
215
213
|
activeDecay();
|
|
216
214
|
return;
|
|
217
215
|
}
|
|
218
|
-
if (!
|
|
216
|
+
if (!loop) {
|
|
219
217
|
translation.value = withSpring(0);
|
|
220
218
|
return;
|
|
221
219
|
}
|
|
@@ -226,7 +224,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
226
224
|
activeDecay();
|
|
227
225
|
return;
|
|
228
226
|
}
|
|
229
|
-
if (!
|
|
227
|
+
if (!loop)
|
|
230
228
|
translation.value = withSpring(-((maxPage - 1) * size));
|
|
231
229
|
}
|
|
232
230
|
}, [
|
|
@@ -235,7 +233,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
235
233
|
maxPage,
|
|
236
234
|
size,
|
|
237
235
|
scrollEndTranslation.value,
|
|
238
|
-
|
|
236
|
+
loop,
|
|
239
237
|
activeDecay,
|
|
240
238
|
withSpring,
|
|
241
239
|
]);
|
|
@@ -252,7 +250,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
252
250
|
function withProcessTranslation(translation: number) {
|
|
253
251
|
"worklet";
|
|
254
252
|
|
|
255
|
-
if (!
|
|
253
|
+
if (!loop && !overscrollEnabled) {
|
|
256
254
|
const limit = getLimit();
|
|
257
255
|
const sign = Math.sign(translation);
|
|
258
256
|
return sign * Math.max(0, Math.min(limit, Math.abs(translation)));
|
|
@@ -261,7 +259,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
261
259
|
return translation;
|
|
262
260
|
}
|
|
263
261
|
|
|
264
|
-
const onGestureBegin = useCallback(() => {
|
|
262
|
+
const onGestureBegin = useCallback((_: PanGestureHandlerEventPayload) => {
|
|
265
263
|
"worklet";
|
|
266
264
|
|
|
267
265
|
touching.value = true;
|
|
@@ -269,7 +267,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
269
267
|
onScrollBegin && runOnJS(onScrollBegin)();
|
|
270
268
|
|
|
271
269
|
max.value = (maxPage - 1) * size;
|
|
272
|
-
if (!
|
|
270
|
+
if (!loop && !overscrollEnabled)
|
|
273
271
|
max.value = getLimit();
|
|
274
272
|
|
|
275
273
|
panOffset.value = translation.value;
|
|
@@ -277,7 +275,7 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
277
275
|
max,
|
|
278
276
|
size,
|
|
279
277
|
maxPage,
|
|
280
|
-
|
|
278
|
+
loop,
|
|
281
279
|
touching,
|
|
282
280
|
panOffset,
|
|
283
281
|
validStart,
|
|
@@ -296,10 +294,18 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
296
294
|
}
|
|
297
295
|
touching.value = true;
|
|
298
296
|
const { translationX, translationY } = e;
|
|
299
|
-
|
|
297
|
+
|
|
298
|
+
let panTranslation = isHorizontal.value
|
|
300
299
|
? translationX
|
|
301
300
|
: translationY;
|
|
302
|
-
|
|
301
|
+
|
|
302
|
+
if (fixedDirection === "negative")
|
|
303
|
+
panTranslation = -Math.abs(panTranslation);
|
|
304
|
+
|
|
305
|
+
else if (fixedDirection === "positive")
|
|
306
|
+
panTranslation = +Math.abs(panTranslation);
|
|
307
|
+
|
|
308
|
+
if (!loop) {
|
|
303
309
|
if ((translation.value > 0 || translation.value < -max.value)) {
|
|
304
310
|
const boundary = translation.value > 0 ? 0 : -max.value;
|
|
305
311
|
const fixed = boundary - panOffset.value;
|
|
@@ -315,24 +321,34 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
315
321
|
isHorizontal,
|
|
316
322
|
max,
|
|
317
323
|
panOffset,
|
|
318
|
-
|
|
324
|
+
loop,
|
|
319
325
|
overscrollEnabled,
|
|
326
|
+
fixedDirection,
|
|
320
327
|
translation,
|
|
321
328
|
validStart,
|
|
322
329
|
touching,
|
|
323
330
|
]);
|
|
324
331
|
|
|
325
|
-
const
|
|
332
|
+
const onGestureEnd = useCallback((e: GestureStateChangeEvent<PanGestureHandlerEventPayload>, _success: boolean) => {
|
|
326
333
|
"worklet";
|
|
327
334
|
|
|
328
335
|
const { velocityX, velocityY, translationX, translationY } = e;
|
|
329
336
|
scrollEndVelocity.value = isHorizontal.value
|
|
330
337
|
? velocityX
|
|
331
338
|
: velocityY;
|
|
332
|
-
|
|
339
|
+
|
|
340
|
+
let panTranslation = isHorizontal.value
|
|
333
341
|
? translationX
|
|
334
342
|
: translationY;
|
|
335
343
|
|
|
344
|
+
if (fixedDirection === "negative")
|
|
345
|
+
panTranslation = -Math.abs(panTranslation);
|
|
346
|
+
|
|
347
|
+
else if (fixedDirection === "positive")
|
|
348
|
+
panTranslation = +Math.abs(panTranslation);
|
|
349
|
+
|
|
350
|
+
scrollEndTranslation.value = panTranslation;
|
|
351
|
+
|
|
336
352
|
const totalTranslation = scrollEndVelocity.value + scrollEndTranslation.value;
|
|
337
353
|
|
|
338
354
|
if (maxScrollDistancePerSwipeIsSet && Math.abs(totalTranslation) > maxScrollDistancePerSwipe) {
|
|
@@ -343,17 +359,18 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
343
359
|
endWithSpring(onScrollEnd);
|
|
344
360
|
}
|
|
345
361
|
|
|
346
|
-
if (!
|
|
362
|
+
if (!loop)
|
|
347
363
|
touching.value = false;
|
|
348
364
|
}, [
|
|
349
365
|
size,
|
|
350
|
-
|
|
366
|
+
loop,
|
|
351
367
|
touching,
|
|
352
368
|
panOffset,
|
|
353
369
|
translation,
|
|
354
370
|
isHorizontal,
|
|
355
371
|
scrollEndVelocity,
|
|
356
372
|
scrollEndTranslation,
|
|
373
|
+
fixedDirection,
|
|
357
374
|
maxScrollDistancePerSwipeIsSet,
|
|
358
375
|
maxScrollDistancePerSwipe,
|
|
359
376
|
endWithSpring,
|
|
@@ -361,25 +378,13 @@ const IScrollViewGesture: React.FC<PropsWithChildren<Props>> = (props) => {
|
|
|
361
378
|
onScrollEnd,
|
|
362
379
|
]);
|
|
363
380
|
|
|
364
|
-
const gesture =
|
|
365
|
-
|
|
366
|
-
.onBegin(onGestureBegin)
|
|
367
|
-
.onUpdate(onGestureUpdate)
|
|
368
|
-
.onEnd(onGestureFinish);
|
|
369
|
-
|
|
370
|
-
if (onConfigurePanGesture)
|
|
371
|
-
onConfigurePanGesture(gesture);
|
|
372
|
-
|
|
373
|
-
return gesture;
|
|
374
|
-
},
|
|
375
|
-
[
|
|
381
|
+
const gesture = usePanGestureProxy({
|
|
382
|
+
onConfigurePanGesture,
|
|
376
383
|
onGestureBegin,
|
|
377
384
|
onGestureUpdate,
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
useUpdateGestureConfig(gesture, { enabled });
|
|
385
|
+
onGestureEnd,
|
|
386
|
+
options: { enabled },
|
|
387
|
+
});
|
|
383
388
|
|
|
384
389
|
return (
|
|
385
390
|
<GestureDetector gesture={gesture}>
|
|
@@ -21,9 +21,10 @@ interface IOpts {
|
|
|
21
21
|
loop: boolean
|
|
22
22
|
size: number
|
|
23
23
|
dataLength: number
|
|
24
|
-
autoFillData: TCarouselProps["autoFillData"]
|
|
25
24
|
handlerOffset: Animated.SharedValue<number>
|
|
25
|
+
autoFillData: TCarouselProps["autoFillData"]
|
|
26
26
|
withAnimation?: TCarouselProps["withAnimation"]
|
|
27
|
+
fixedDirection?: TCarouselProps["fixedDirection"]
|
|
27
28
|
duration?: number
|
|
28
29
|
defaultIndex?: number
|
|
29
30
|
onScrollBegin?: () => void
|
|
@@ -48,6 +49,7 @@ export function useCarouselController(options: IOpts): ICarouselController {
|
|
|
48
49
|
defaultIndex = 0,
|
|
49
50
|
duration,
|
|
50
51
|
autoFillData,
|
|
52
|
+
fixedDirection,
|
|
51
53
|
} = options;
|
|
52
54
|
|
|
53
55
|
const dataInfo = React.useMemo(
|
|
@@ -241,7 +243,7 @@ export function useCarouselController(options: IOpts): ICarouselController {
|
|
|
241
243
|
|
|
242
244
|
onScrollBegin?.();
|
|
243
245
|
// direction -> 1 | -1
|
|
244
|
-
const direction = handlerOffsetDirection(handlerOffset);
|
|
246
|
+
const direction = handlerOffsetDirection(handlerOffset, fixedDirection);
|
|
245
247
|
|
|
246
248
|
// target offset
|
|
247
249
|
const offset = i * size * direction;
|
|
@@ -252,16 +254,16 @@ export function useCarouselController(options: IOpts): ICarouselController {
|
|
|
252
254
|
|
|
253
255
|
if (loop) {
|
|
254
256
|
isCloseToNextLoop
|
|
255
|
-
|
|
256
|
-
|
|
257
|
+
= Math.abs(handlerOffset.value % totalSize) / totalSize
|
|
258
|
+
>= 0.5;
|
|
257
259
|
}
|
|
258
260
|
|
|
259
261
|
const finalOffset
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
262
|
+
= (Math.floor(Math.abs(handlerOffset.value / totalSize))
|
|
263
|
+
+ (isCloseToNextLoop ? 1 : 0))
|
|
264
|
+
* totalSize
|
|
265
|
+
* direction
|
|
266
|
+
+ offset;
|
|
265
267
|
|
|
266
268
|
if (animated) {
|
|
267
269
|
index.value = i;
|
|
@@ -274,13 +276,14 @@ export function useCarouselController(options: IOpts): ICarouselController {
|
|
|
274
276
|
}
|
|
275
277
|
},
|
|
276
278
|
[
|
|
279
|
+
size,
|
|
280
|
+
loop,
|
|
277
281
|
index,
|
|
278
|
-
|
|
279
|
-
onScrollBegin,
|
|
282
|
+
fixedDirection,
|
|
280
283
|
handlerOffset,
|
|
281
|
-
size,
|
|
282
284
|
dataInfo.length,
|
|
283
|
-
|
|
285
|
+
canSliding,
|
|
286
|
+
onScrollBegin,
|
|
284
287
|
scrollWithTiming,
|
|
285
288
|
],
|
|
286
289
|
);
|
|
@@ -2,8 +2,8 @@ import React from "react";
|
|
|
2
2
|
|
|
3
3
|
import type { TInitializeCarouselProps } from "./useInitProps";
|
|
4
4
|
|
|
5
|
+
import type { TAnimationStyle } from "../components/BaseLayout";
|
|
5
6
|
import { Layouts } from "../layouts";
|
|
6
|
-
import type { TAnimationStyle } from "../layouts/BaseLayout";
|
|
7
7
|
|
|
8
8
|
type TLayoutConfigOpts<T> = TInitializeCarouselProps<T> & { size: number };
|
|
9
9
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useSharedValue } from "react-native-reanimated";
|
|
2
|
+
|
|
3
|
+
import { renderHook } from "@testing-library/react-hooks";
|
|
4
|
+
|
|
5
|
+
import type { IOpts } from "./useOffsetX";
|
|
6
|
+
import { useOffsetX } from "./useOffsetX";
|
|
7
|
+
import type { IVisibleRanges } from "./useVisibleRanges";
|
|
8
|
+
|
|
9
|
+
describe("useSharedValue", () => {
|
|
10
|
+
it("should return the correct values", async () => {
|
|
11
|
+
const hook = renderHook(() => {
|
|
12
|
+
const range = useSharedValue({
|
|
13
|
+
negativeRange: [7, 9],
|
|
14
|
+
positiveRange: [0, 3],
|
|
15
|
+
});
|
|
16
|
+
const inputs: Array<{
|
|
17
|
+
config: IOpts
|
|
18
|
+
range: IVisibleRanges
|
|
19
|
+
}> = Array.from({ length: 10 }).map((_, index) => ({
|
|
20
|
+
config: {
|
|
21
|
+
dataLength: 10,
|
|
22
|
+
handlerOffset: useSharedValue(-0),
|
|
23
|
+
index,
|
|
24
|
+
loop: false,
|
|
25
|
+
size: 393,
|
|
26
|
+
},
|
|
27
|
+
range,
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
return inputs.map((input) => {
|
|
31
|
+
const { config, range } = input;
|
|
32
|
+
|
|
33
|
+
return useOffsetX(config, range);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const expected = hook.result.current.map(v => v.value).slice();
|
|
38
|
+
|
|
39
|
+
expect(expected).toMatchInlineSnapshot(`
|
|
40
|
+
[
|
|
41
|
+
0,
|
|
42
|
+
393,
|
|
43
|
+
786,
|
|
44
|
+
1179,
|
|
45
|
+
9007199254740991,
|
|
46
|
+
9007199254740991,
|
|
47
|
+
9007199254740991,
|
|
48
|
+
2751,
|
|
49
|
+
3144,
|
|
50
|
+
3537,
|
|
51
|
+
]
|
|
52
|
+
`);
|
|
53
|
+
});
|
|
54
|
+
});
|
package/src/hooks/useOffsetX.ts
CHANGED
|
@@ -35,7 +35,7 @@ export const useOffsetX = (opts: IOpts, visibleRanges: IVisibleRanges) => {
|
|
|
35
35
|
|
|
36
36
|
const viewCount = _viewCount ?? Math.round((ITEM_LENGTH - 1) / 2);
|
|
37
37
|
const positiveCount
|
|
38
|
-
|
|
38
|
+
= type === "positive" ? viewCount : VALID_LENGTH - viewCount;
|
|
39
39
|
|
|
40
40
|
let startPos = size * index;
|
|
41
41
|
if (index > positiveCount)
|
|
@@ -46,42 +46,44 @@ export const useOffsetX = (opts: IOpts, visibleRanges: IVisibleRanges) => {
|
|
|
46
46
|
|
|
47
47
|
const x = useDerivedValue(() => {
|
|
48
48
|
const { negativeRange, positiveRange } = visibleRanges.value;
|
|
49
|
+
|
|
49
50
|
if (
|
|
50
|
-
(index
|
|
51
|
-
|
|
52
|
-
)
|
|
53
|
-
|
|
51
|
+
(index >= negativeRange[0] && index <= negativeRange[1])
|
|
52
|
+
|| (index >= positiveRange[0] && index <= positiveRange[1])
|
|
53
|
+
) {
|
|
54
|
+
if (loop) {
|
|
55
|
+
const inputRange = [
|
|
56
|
+
-TOTAL_WIDTH,
|
|
57
|
+
MIN - HALF_WIDTH - startPos - Number.MIN_VALUE,
|
|
58
|
+
MIN - HALF_WIDTH - startPos,
|
|
59
|
+
0,
|
|
60
|
+
MAX + HALF_WIDTH - startPos,
|
|
61
|
+
MAX + HALF_WIDTH - startPos + Number.MIN_VALUE,
|
|
62
|
+
TOTAL_WIDTH,
|
|
63
|
+
];
|
|
54
64
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
];
|
|
65
|
+
const outputRange = [
|
|
66
|
+
startPos,
|
|
67
|
+
MAX + HALF_WIDTH - Number.MIN_VALUE,
|
|
68
|
+
MIN - HALF_WIDTH,
|
|
69
|
+
startPos,
|
|
70
|
+
MAX + HALF_WIDTH,
|
|
71
|
+
MIN - HALF_WIDTH + Number.MIN_VALUE,
|
|
72
|
+
startPos,
|
|
73
|
+
];
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
startPos,
|
|
74
|
-
];
|
|
75
|
+
return interpolate(
|
|
76
|
+
handlerOffset.value,
|
|
77
|
+
inputRange,
|
|
78
|
+
outputRange,
|
|
79
|
+
Extrapolate.CLAMP,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
75
82
|
|
|
76
|
-
return
|
|
77
|
-
handlerOffset.value,
|
|
78
|
-
inputRange,
|
|
79
|
-
outputRange,
|
|
80
|
-
Extrapolate.CLAMP,
|
|
81
|
-
);
|
|
83
|
+
return handlerOffset.value + size * index;
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
return
|
|
86
|
+
return Number.MAX_SAFE_INTEGER;
|
|
85
87
|
}, [loop, dataLength, viewCount, type, size, visibleRanges]);
|
|
86
88
|
|
|
87
89
|
return x;
|