@momo-kits/carousel 0.159.1-beta.4 → 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.
Files changed (2) hide show
  1. package/index.tsx +94 -55
  2. 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 scrollXRef = useRef(new Animated.Value(0)).current;
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
- (event: NativeSyntheticEvent<NativeScrollEvent>) => {
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
- <Animated.View
378
- style={[
379
- { width: itemWidth },
380
- slideStyle,
381
- {
382
- opacity,
383
- transform: [{ scale }],
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
- </Animated.View>
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
- scrollXRef,
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 onScrollEvent = useMemo(() => {
413
- const scrollHandler = Animated.event(
414
- [{ nativeEvent: { contentOffset: { x: scrollXRef } } }],
415
- {
416
- useNativeDriver: true,
417
- listener: handleScroll,
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
- if (onScrollProp) {
422
- return (event: NativeSyntheticEvent<NativeScrollEvent>) => {
423
- scrollHandler(event);
424
- onScrollProp(event);
425
- };
426
- }
458
+ },
459
+ [onScrollProp],
460
+ );
427
461
 
428
- return scrollHandler;
429
- }, [scrollXRef, handleScroll, onScrollProp]);
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/carousel",
3
- "version": "0.159.1-beta.4",
3
+ "version": "0.160.1-beta.7",
4
4
  "private": false,
5
5
  "main": "index.tsx",
6
6
  "peerDependencies": {