@momo-kits/carousel 0.159.1-beta.5 → 0.160.1-beta.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/index.tsx +94 -55
- package/package.json +1 -1
package/index.tsx
CHANGED
|
@@ -8,7 +8,6 @@ import React, {
|
|
|
8
8
|
useState,
|
|
9
9
|
} from 'react';
|
|
10
10
|
import {
|
|
11
|
-
Animated,
|
|
12
11
|
Dimensions,
|
|
13
12
|
FlatList,
|
|
14
13
|
GestureResponderEvent,
|
|
@@ -17,14 +16,79 @@ import {
|
|
|
17
16
|
NativeSyntheticEvent,
|
|
18
17
|
Platform,
|
|
19
18
|
StyleSheet,
|
|
20
|
-
View
|
|
19
|
+
View,
|
|
21
20
|
} from 'react-native';
|
|
21
|
+
import Animated, {
|
|
22
|
+
Extrapolation,
|
|
23
|
+
interpolate,
|
|
24
|
+
runOnJS,
|
|
25
|
+
useAnimatedScrollHandler,
|
|
26
|
+
useAnimatedStyle,
|
|
27
|
+
useSharedValue,
|
|
28
|
+
type SharedValue,
|
|
29
|
+
} from 'react-native-reanimated';
|
|
22
30
|
import { CarouselProps, CarouselRef } from './types';
|
|
23
31
|
|
|
24
32
|
const { width: viewportWidth } = Dimensions.get('window');
|
|
25
33
|
|
|
26
34
|
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
|
|
27
35
|
|
|
36
|
+
type CarouselItemProps = {
|
|
37
|
+
index: number;
|
|
38
|
+
itemWidth: number;
|
|
39
|
+
scrollX: SharedValue<number>;
|
|
40
|
+
inactiveSlideOpacity: number;
|
|
41
|
+
inactiveSlideScale: number;
|
|
42
|
+
slideStyle: any;
|
|
43
|
+
children: React.ReactNode;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const CarouselItem: React.FC<CarouselItemProps> = ({
|
|
47
|
+
index,
|
|
48
|
+
itemWidth,
|
|
49
|
+
scrollX,
|
|
50
|
+
inactiveSlideOpacity,
|
|
51
|
+
inactiveSlideScale,
|
|
52
|
+
slideStyle,
|
|
53
|
+
children,
|
|
54
|
+
}) => {
|
|
55
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
56
|
+
const inputRange = [
|
|
57
|
+
(index - 1) * itemWidth,
|
|
58
|
+
index * itemWidth,
|
|
59
|
+
(index + 1) * itemWidth,
|
|
60
|
+
];
|
|
61
|
+
const opacity =
|
|
62
|
+
inactiveSlideOpacity < 1
|
|
63
|
+
? interpolate(
|
|
64
|
+
scrollX.value,
|
|
65
|
+
inputRange,
|
|
66
|
+
[inactiveSlideOpacity, 1, inactiveSlideOpacity],
|
|
67
|
+
Extrapolation.CLAMP,
|
|
68
|
+
)
|
|
69
|
+
: 1;
|
|
70
|
+
const scale =
|
|
71
|
+
inactiveSlideScale < 1
|
|
72
|
+
? interpolate(
|
|
73
|
+
scrollX.value,
|
|
74
|
+
inputRange,
|
|
75
|
+
[inactiveSlideScale, 1, inactiveSlideScale],
|
|
76
|
+
Extrapolation.CLAMP,
|
|
77
|
+
)
|
|
78
|
+
: 1;
|
|
79
|
+
return {
|
|
80
|
+
opacity,
|
|
81
|
+
transform: [{ scale }],
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Animated.View style={[{ width: itemWidth }, slideStyle, animatedStyle]}>
|
|
87
|
+
{children}
|
|
88
|
+
</Animated.View>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
28
92
|
const Carousel = forwardRef<CarouselRef, CarouselProps>((props, ref) => {
|
|
29
93
|
const {
|
|
30
94
|
data,
|
|
@@ -62,7 +126,7 @@ const Carousel = forwardRef<CarouselRef, CarouselProps>((props, ref) => {
|
|
|
62
126
|
|
|
63
127
|
const flatListRef = useRef<FlatList>(null);
|
|
64
128
|
const autoplayTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
65
|
-
const
|
|
129
|
+
const scrollX = useSharedValue(0);
|
|
66
130
|
const containerWidthRef = useRef(viewportWidth);
|
|
67
131
|
const isAutoplayPausedRef = useRef(false);
|
|
68
132
|
const currentIndexRef = useRef(firstItem);
|
|
@@ -246,15 +310,14 @@ const Carousel = forwardRef<CarouselRef, CarouselProps>((props, ref) => {
|
|
|
246
310
|
);
|
|
247
311
|
|
|
248
312
|
const handleScroll = useCallback(
|
|
249
|
-
(
|
|
250
|
-
const offsetX = event.nativeEvent.contentOffset.x;
|
|
313
|
+
(offsetX: number) => {
|
|
251
314
|
const index = Math.round(offsetX / itemWidth);
|
|
252
315
|
const realIndex = getRealIndex(index);
|
|
253
316
|
|
|
254
317
|
if (realIndex !== currentIndexRef.current) {
|
|
255
318
|
currentIndexRef.current = realIndex;
|
|
256
319
|
setCurrentIndex(realIndex);
|
|
257
|
-
|
|
320
|
+
|
|
258
321
|
if (onScrollIndexChanged) {
|
|
259
322
|
onScrollIndexChanged(realIndex);
|
|
260
323
|
}
|
|
@@ -351,41 +414,17 @@ const Carousel = forwardRef<CarouselRef, CarouselProps>((props, ref) => {
|
|
|
351
414
|
);
|
|
352
415
|
}
|
|
353
416
|
|
|
354
|
-
const inputRange = [
|
|
355
|
-
(index - 1) * itemWidth,
|
|
356
|
-
index * itemWidth,
|
|
357
|
-
(index + 1) * itemWidth,
|
|
358
|
-
];
|
|
359
|
-
|
|
360
|
-
const opacity = hasOpacityAnimation
|
|
361
|
-
? scrollXRef.interpolate({
|
|
362
|
-
inputRange,
|
|
363
|
-
outputRange: [inactiveSlideOpacity, 1, inactiveSlideOpacity],
|
|
364
|
-
extrapolate: 'clamp',
|
|
365
|
-
})
|
|
366
|
-
: 1;
|
|
367
|
-
|
|
368
|
-
const scale = hasScaleAnimation
|
|
369
|
-
? scrollXRef.interpolate({
|
|
370
|
-
inputRange,
|
|
371
|
-
outputRange: [inactiveSlideScale, 1, inactiveSlideScale],
|
|
372
|
-
extrapolate: 'clamp',
|
|
373
|
-
})
|
|
374
|
-
: 1;
|
|
375
|
-
|
|
376
417
|
return (
|
|
377
|
-
<
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
},
|
|
385
|
-
]}
|
|
418
|
+
<CarouselItem
|
|
419
|
+
index={index}
|
|
420
|
+
itemWidth={itemWidth}
|
|
421
|
+
scrollX={scrollX}
|
|
422
|
+
inactiveSlideOpacity={inactiveSlideOpacity}
|
|
423
|
+
inactiveSlideScale={inactiveSlideScale}
|
|
424
|
+
slideStyle={slideStyle}
|
|
386
425
|
>
|
|
387
426
|
{renderItem({ item, index: realIndex })}
|
|
388
|
-
</
|
|
427
|
+
</CarouselItem>
|
|
389
428
|
);
|
|
390
429
|
},
|
|
391
430
|
[
|
|
@@ -395,7 +434,7 @@ const Carousel = forwardRef<CarouselRef, CarouselProps>((props, ref) => {
|
|
|
395
434
|
itemWidth,
|
|
396
435
|
slideStyle,
|
|
397
436
|
renderItem,
|
|
398
|
-
|
|
437
|
+
scrollX,
|
|
399
438
|
]
|
|
400
439
|
);
|
|
401
440
|
|
|
@@ -409,24 +448,24 @@ const Carousel = forwardRef<CarouselRef, CarouselProps>((props, ref) => {
|
|
|
409
448
|
[keyExtractor]
|
|
410
449
|
);
|
|
411
450
|
|
|
412
|
-
const
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
451
|
+
const emitScrollProp = useCallback(
|
|
452
|
+
(offsetX: number) => {
|
|
453
|
+
if (onScrollProp) {
|
|
454
|
+
onScrollProp({
|
|
455
|
+
nativeEvent: { contentOffset: { x: offsetX, y: 0 } },
|
|
456
|
+
} as NativeSyntheticEvent<NativeScrollEvent>);
|
|
418
457
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
return (event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
423
|
-
scrollHandler(event);
|
|
424
|
-
onScrollProp(event);
|
|
425
|
-
};
|
|
426
|
-
}
|
|
458
|
+
},
|
|
459
|
+
[onScrollProp],
|
|
460
|
+
);
|
|
427
461
|
|
|
428
|
-
|
|
429
|
-
|
|
462
|
+
const onScrollEvent = useAnimatedScrollHandler({
|
|
463
|
+
onScroll: (event) => {
|
|
464
|
+
scrollX.value = event.contentOffset.x;
|
|
465
|
+
runOnJS(handleScroll)(event.contentOffset.x);
|
|
466
|
+
runOnJS(emitScrollProp)(event.contentOffset.x);
|
|
467
|
+
},
|
|
468
|
+
});
|
|
430
469
|
|
|
431
470
|
useEffect(() => {
|
|
432
471
|
if (isLayoutReady && firstItem > 0 && firstItem < data.length) {
|