react-native-reanimated-carousel 1.0.7 → 1.0.11
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 +40 -51
- package/README.zh-CN.md +41 -52
- package/lib/commonjs/Carousel.js +96 -120
- package/lib/commonjs/Carousel.js.map +1 -1
- package/lib/commonjs/CarouselItem.js +35 -14
- package/lib/commonjs/CarouselItem.js.map +1 -1
- package/lib/commonjs/LazyView.js +26 -0
- package/lib/commonjs/LazyView.js.map +1 -0
- package/lib/commonjs/ScrollViewGesture.js +196 -0
- package/lib/commonjs/ScrollViewGesture.js.map +1 -0
- package/lib/commonjs/hooks/useCarouselController.js +9 -9
- package/lib/commonjs/hooks/useCarouselController.js.map +1 -1
- package/lib/commonjs/hooks/useIndexController.js +3 -3
- package/lib/commonjs/hooks/useIndexController.js.map +1 -1
- package/lib/commonjs/hooks/useOffsetX.js +20 -33
- package/lib/commonjs/hooks/useOffsetX.js.map +1 -1
- package/lib/commonjs/hooks/usePropsErrorBoundary.js +11 -2
- package/lib/commonjs/hooks/usePropsErrorBoundary.js.map +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.js +42 -0
- package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/layouts/ParallaxLayout.js +55 -19
- package/lib/commonjs/layouts/ParallaxLayout.js.map +1 -1
- package/lib/commonjs/types.js +6 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/utils/log.js +2 -2
- package/lib/commonjs/utils/log.js.map +1 -1
- package/lib/module/Carousel.js +92 -117
- package/lib/module/Carousel.js.map +1 -1
- package/lib/module/CarouselItem.js +31 -14
- package/lib/module/CarouselItem.js.map +1 -1
- package/lib/module/LazyView.js +14 -0
- package/lib/module/LazyView.js.map +1 -0
- package/lib/module/ScrollViewGesture.js +172 -0
- package/lib/module/ScrollViewGesture.js.map +1 -0
- package/lib/module/hooks/useCarouselController.js +9 -9
- package/lib/module/hooks/useCarouselController.js.map +1 -1
- package/lib/module/hooks/useIndexController.js +3 -3
- package/lib/module/hooks/useIndexController.js.map +1 -1
- package/lib/module/hooks/useOffsetX.js +20 -33
- package/lib/module/hooks/useOffsetX.js.map +1 -1
- package/lib/module/hooks/usePropsErrorBoundary.js +11 -2
- package/lib/module/hooks/usePropsErrorBoundary.js.map +1 -1
- package/lib/module/hooks/useVisibleRanges.js +34 -0
- package/lib/module/hooks/useVisibleRanges.js.map +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/layouts/ParallaxLayout.js +49 -21
- package/lib/module/layouts/ParallaxLayout.js.map +1 -1
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils/log.js +2 -2
- package/lib/module/utils/log.js.map +1 -1
- package/lib/typescript/Carousel.d.ts +3 -113
- package/lib/typescript/CarouselItem.d.ts +5 -3
- package/lib/typescript/LazyView.d.ts +6 -0
- package/lib/typescript/ScrollViewGesture.d.ts +18 -0
- package/lib/typescript/hooks/useCarouselController.d.ts +1 -1
- package/lib/typescript/hooks/useIndexController.d.ts +1 -1
- package/lib/typescript/hooks/useOffsetX.d.ts +3 -2
- package/lib/typescript/hooks/usePropsErrorBoundary.d.ts +2 -2
- package/lib/typescript/hooks/useVisibleRanges.d.ts +11 -0
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/layouts/ParallaxLayout.d.ts +4 -0
- package/lib/typescript/types.d.ts +129 -0
- package/lib/typescript/utils/log.d.ts +1 -1
- package/package.json +1 -1
- package/src/Carousel.tsx +104 -269
- package/src/CarouselItem.tsx +62 -16
- package/src/LazyView.tsx +15 -0
- package/src/ScrollViewGesture.tsx +249 -0
- package/src/hooks/useCarouselController.tsx +10 -10
- package/src/hooks/useIndexController.ts +4 -4
- package/src/hooks/useOffsetX.ts +22 -38
- package/src/hooks/usePropsErrorBoundary.ts +12 -4
- package/src/hooks/useVisibleRanges.tsx +42 -0
- package/src/index.tsx +1 -1
- package/src/layouts/ParallaxLayout.tsx +89 -27
- package/src/types.ts +137 -0
- package/src/utils/log.ts +2 -2
package/README.md
CHANGED
|
@@ -11,29 +11,22 @@ English | [简体中文](./README.zh-CN.md)
|
|
|
11
11
|
[](https://github.com/dohooo/react-native-reanimated-carousel/issues?q=is%3Aissue+is%3Aclosed)
|
|
12
12
|
|
|
13
13
|
<p align="center">
|
|
14
|
-
<img src="assets/normal.gif" width="300"/>
|
|
14
|
+
<img src="assets/normal-horizontal.gif" width="300"/>
|
|
15
|
+
<img src="assets/normal-vertical.gif" width="300"/>
|
|
16
|
+
<img src="assets/parallax-horizontal.gif" width="300"/>
|
|
17
|
+
<img src="assets/parallax-vertical.gif" width="300"/>
|
|
15
18
|
</p>
|
|
16
19
|
|
|
17
20
|
<br/>
|
|
18
21
|
|
|
19
|
-
##
|
|
22
|
+
## ReactNative community's best use of the carousel component! 🎉🎉🎉
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Updates:
|
|
24
|
-
|
|
25
|
-
- Reconstructed some logic, sliding animation more smooth, natural
|
|
26
|
-
- timingConfig -> springConfig (The configuration of the 'duration' property is no longer supported by this configuration)
|
|
27
|
-
- [...](https://github.com/dohooo/react-native-reanimated-carousel/releases/tag/v1.0.0)
|
|
24
|
+
- It completely solves this [problem](https://github.com/meliorence/react-native-snap-carousel/issues/632) for `react-native-snap-carousel`! More styles and apis in development... [Try it](https://snack.expo.dev/@zhaodonghao586/simple-carousel)
|
|
25
|
+
- **Simple**、**Infinitely scrolling very smooth**、**Fully implemented using Reanimated 2!**
|
|
28
26
|
|
|
29
27
|
## Reason
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
> The common RN infinite scroll component. It's common to get stuck on a fast slide. Wait for the next element to appear. This component will not have similar problems. That's why this library was created.
|
|
34
|
-
|
|
35
|
-
> At present, it only meets the needs of my work. Welcome to raise PR/ISSUES.[Try it with snack](https://snack.expo.dev/@zhaodonghao586/simple-carousel)
|
|
36
|
-
|
|
28
|
+
<details>
|
|
29
|
+
<summary>The common RN infinite scroll component. It get stuck on a fast slide. Wait for the next element to appear. This component will not have similar problems.Because using a completely different approach so the best performance is achieved.That's why this library was created.</summary>
|
|
37
30
|
<p align="center">
|
|
38
31
|
Use react-native-snap-carousel for quick swiping,you can see caton clearly when you reach the junction.(gif 4.6mb)
|
|
39
32
|
</p>
|
|
@@ -42,11 +35,12 @@ Updates:
|
|
|
42
35
|
</p>
|
|
43
36
|
|
|
44
37
|
<p align="center">
|
|
45
|
-
Compared with react-native-reanimated-carousel,The actual test was ten slides per second, but it didn't show up very well in gif
|
|
38
|
+
Compared with react-native-reanimated-carousel,The actual test was ten slides per second, but it didn't show up very well in gif.
|
|
46
39
|
</p>
|
|
47
40
|
<p align="center">
|
|
48
|
-
<img src="assets/fast.gif" width="50%"/>
|
|
41
|
+
<img src="assets/normal-fast.gif" width="50%"/>
|
|
49
42
|
</p>
|
|
43
|
+
</details>
|
|
50
44
|
|
|
51
45
|
---
|
|
52
46
|
|
|
@@ -72,51 +66,46 @@ If use EXPO managed workflow please ensure that the version is greater than 41.B
|
|
|
72
66
|
|
|
73
67
|
## Usage
|
|
74
68
|
|
|
75
|
-
```
|
|
69
|
+
```tsx
|
|
76
70
|
import Carousel from 'react-native-reanimated-carousel';
|
|
77
71
|
|
|
78
|
-
// ...
|
|
79
|
-
|
|
80
72
|
<Carousel<{ color: string }>
|
|
81
73
|
width={width}
|
|
82
74
|
data={[{ color: 'red' }, { color: 'purple' }, { color: 'yellow' }]}
|
|
83
75
|
renderItem={({ color }) => {
|
|
84
|
-
return
|
|
85
|
-
<View
|
|
86
|
-
style={{
|
|
87
|
-
backgroundColor: color,
|
|
88
|
-
justifyContent: 'center',
|
|
89
|
-
flex: 1,
|
|
90
|
-
}}
|
|
91
|
-
/>
|
|
92
|
-
);
|
|
76
|
+
return <View style={{ backgroundColor: color, flex: 1 }} />;
|
|
93
77
|
}}
|
|
94
78
|
/>;
|
|
95
79
|
```
|
|
96
80
|
|
|
81
|
+
## Optimizing
|
|
82
|
+
|
|
83
|
+
- When rendering a large number of elements, you can use the 'windowSize' property to control how many items of the current element are rendered. The default is full rendering. After testing without this property, frames will drop when rendering 200 empty views. After setting this property, rendering 1000 empty views is still smooth. (The specific number depends on the phone model tested)
|
|
84
|
+
|
|
97
85
|
## Props
|
|
98
86
|
|
|
99
|
-
| name | required | default
|
|
100
|
-
| ----------------------- | -------- |
|
|
101
|
-
| data | ✅ |
|
|
102
|
-
| width | ✅ |
|
|
103
|
-
| renderItem | ✅ |
|
|
104
|
-
| defaultIndex | ❌ | 0
|
|
105
|
-
| autoPlay | ❌ | false
|
|
106
|
-
| autoPlayReverse | ❌ | false
|
|
107
|
-
| autoPlayInterval | ❌ | 1000
|
|
108
|
-
| mode | ❌ | defalut
|
|
109
|
-
| loop | ❌ | true
|
|
110
|
-
| parallaxScrollingOffset | ❌ | 100
|
|
111
|
-
| parallaxScrollingScale | ❌ | 0.8
|
|
112
|
-
| style | ❌ | {}
|
|
113
|
-
| height | ❌ | '100%'
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
| onProgressChange | ❌ |
|
|
87
|
+
| name | required | default | types | description |
|
|
88
|
+
| ----------------------- | -------- | ------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
89
|
+
| data | ✅ | | T[] | Carousel items data set |
|
|
90
|
+
| width | ✅ | | number | Specified carousel container width |
|
|
91
|
+
| renderItem | ✅ | | (data: T, index: number) => React.ReactNode | Render carousel item |
|
|
92
|
+
| defaultIndex | ❌ | 0 | number | Default index |
|
|
93
|
+
| autoPlay | ❌ | false | boolean | Auto play |
|
|
94
|
+
| autoPlayReverse | ❌ | false | boolean | Auto play reverse playback |
|
|
95
|
+
| autoPlayInterval | ❌ | 1000 | autoPlayInterval | Auto play playback interval |
|
|
96
|
+
| mode | ❌ | defalut | 'default'\|'parallax' | Carousel Animated transitions |
|
|
97
|
+
| loop | ❌ | true | boolean | Carousel loop playback |
|
|
98
|
+
| parallaxScrollingOffset | ❌ | 100 | number | When use 'parallax' Layout props,this prop can be control prev/next item offset |
|
|
99
|
+
| parallaxScrollingScale | ❌ | 0.8 | number | When use 'parallax' Layout props,this prop can be control prev/next item scale |
|
|
100
|
+
| style | ❌ | {} | ViewStyle | Carousel container style |
|
|
101
|
+
| height | ❌ | '100%' | undefined \| string \| number | Specified carousel container height |
|
|
102
|
+
| onSnapToItem | ❌ | | (index: number) => void | Callback fired when navigating to an item |
|
|
103
|
+
| onScrollBegin | ❌ | | () => void | Callback fired when scroll begin |
|
|
104
|
+
| onScrollEnd | ❌ | | (previous: number, current: number) => void | Callback fired when scroll end |
|
|
105
|
+
| panGestureHandlerProps | ❌ | {} | Omit<Partial\<PanGestureHandlerProps\>,'onHandlerStateChange'> | PanGestureHandler props |
|
|
106
|
+
| windowSize | ❌ | 0 | number | The maximum number of items that can respond to pan gesture events, `0` means all items will respond to pan gesture events |
|
|
107
|
+
| onProgressChange | ❌ | | onProgressChange?: (offsetProgress: number,absoluteProgress: number) => void | On progress change. `offsetProgress`:Total of offset distance (0 390 780 ...); `absoluteProgress`:Convert to index (0 1 2 ...) |
|
|
108
|
+
| vertical | ❌ | false | boolean | Layout items vertically instead of horizontally |
|
|
120
109
|
|
|
121
110
|
## Ref
|
|
122
111
|
|
package/README.zh-CN.md
CHANGED
|
@@ -11,30 +11,23 @@
|
|
|
11
11
|
[](https://github.com/dohooo/react-native-reanimated-carousel/issues?q=is%3Aissue+is%3Aclosed)
|
|
12
12
|
|
|
13
13
|
<p align="center">
|
|
14
|
-
<img src="assets/normal.gif" width="300"/>
|
|
14
|
+
<img src="assets/normal-horizontal.gif" width="300"/>
|
|
15
|
+
<img src="assets/normal-vertical.gif" width="300"/>
|
|
16
|
+
<img src="assets/parallax-horizontal.gif" width="300"/>
|
|
17
|
+
<img src="assets/parallax-vertical.gif" width="300"/>
|
|
15
18
|
</p>
|
|
16
19
|
|
|
17
20
|
<br/>
|
|
18
21
|
|
|
19
|
-
##
|
|
22
|
+
## ReactNative 社区最好用的轮播图组件! 🎉🎉🎉
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
更新:
|
|
24
|
-
|
|
25
|
-
- 重构了部分逻辑,滑动动画更加流畅、自然
|
|
26
|
-
- timingConfig -> springConfig (此配置不再支持对`duration`属性的配置)
|
|
27
|
-
- [...](https://github.com/dohooo/react-native-reanimated-carousel/releases/tag/v1.0.0)
|
|
24
|
+
- 完全解决了`react-native-snap-carousel`的[问题](https://github.com/meliorence/react-native-snap-carousel/issues/632)! 更多样式与API正在开发中...[试一下](https://snack.expo.dev/@zhaodonghao586/simple-carousel)
|
|
25
|
+
- **易用**、**无限滚动**、**完全使用 Reanimated2 实现**
|
|
28
26
|
|
|
29
27
|
## 原因
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
> 常见的无限滚动轮播图,在快速滑动时会出现卡住的情况,这是因为实现方式而导致的问题。这个组件用了不同的方式来实现,解决了这个问题,这就是创建这个库的原因。
|
|
34
|
-
|
|
35
|
-
> 目前他只满足了我工作上的需要,欢迎大家的 ISSUES/PR。[在 SNACK 上尝试](https://snack.expo.dev/@zhaodonghao586/simple-carousel)
|
|
36
|
-
|
|
37
|
-
<p align="center">
|
|
28
|
+
<details>
|
|
29
|
+
<summary>常见的无限滚动轮播图,在快速滑动时会出现卡住的情况,这是因为实现方式而导致的问题。所以这个组件用了完全不同的方式来实现,并获得了最佳的性能也解决了这个问题,这就是创建这个库的原因。</summary>
|
|
30
|
+
<p align="center">
|
|
38
31
|
使用react-native-snap-carousel快速滑动,当到连接处时可以看清楚的看到卡顿。(gif 4.6mb)
|
|
39
32
|
</p>
|
|
40
33
|
<p align="center">
|
|
@@ -42,11 +35,12 @@
|
|
|
42
35
|
</p>
|
|
43
36
|
|
|
44
37
|
<p align="center">
|
|
45
|
-
使用react-native-reanimated-carousel对比,每秒滚动十张依然顺畅链接,无限滚动。这里使用了gif
|
|
38
|
+
使用react-native-reanimated-carousel对比,每秒滚动十张依然顺畅链接,无限滚动。这里使用了gif无法很清晰的看出。
|
|
46
39
|
</p>
|
|
47
40
|
<p align="center">
|
|
48
|
-
<img src="assets/fast.gif" width="50%"/>
|
|
41
|
+
<img src="assets/normal-fast.gif" width="50%"/>
|
|
49
42
|
</p>
|
|
43
|
+
</details>
|
|
50
44
|
|
|
51
45
|
---
|
|
52
46
|
|
|
@@ -72,51 +66,46 @@ npm install react-native-reanimated-carousel
|
|
|
72
66
|
|
|
73
67
|
## 使用
|
|
74
68
|
|
|
75
|
-
```
|
|
69
|
+
```tsx
|
|
76
70
|
import Carousel from 'react-native-reanimated-carousel';
|
|
77
71
|
|
|
78
|
-
// ...
|
|
79
|
-
|
|
80
72
|
<Carousel<{ color: string }>
|
|
81
73
|
width={width}
|
|
82
74
|
data={[{ color: 'red' }, { color: 'purple' }, { color: 'yellow' }]}
|
|
83
75
|
renderItem={({ color }) => {
|
|
84
|
-
return
|
|
85
|
-
<View
|
|
86
|
-
style={{
|
|
87
|
-
backgroundColor: color,
|
|
88
|
-
justifyContent: 'center',
|
|
89
|
-
flex: 1,
|
|
90
|
-
}}
|
|
91
|
-
/>
|
|
92
|
-
);
|
|
76
|
+
return <View style={{ backgroundColor: color, flex: 1 }} />;
|
|
93
77
|
}}
|
|
94
78
|
/>;
|
|
95
79
|
```
|
|
96
80
|
|
|
81
|
+
## 优化
|
|
82
|
+
|
|
83
|
+
- 当渲染大量元素时,可使用`windowSize`属性,来控制当前元素的两侧渲染数量,默认为全量渲染。经测试不加此属性,渲染 200 个空 view 时会出现掉帧情况,设置此属性后渲染 1000 个空 view 依旧流畅。(具体数量与测试的手机型号相关)
|
|
84
|
+
|
|
97
85
|
## Props
|
|
98
86
|
|
|
99
|
-
| name | required | default
|
|
100
|
-
| ----------------------- | -------- |
|
|
101
|
-
| data | ✅ |
|
|
102
|
-
| width | ✅ |
|
|
103
|
-
| renderItem | ✅ |
|
|
104
|
-
| defaultIndex | ❌ | 0
|
|
105
|
-
| autoPlay | ❌ | false
|
|
106
|
-
| autoPlayReverse | ❌ | false
|
|
107
|
-
| autoPlayInterval | ❌ | 1000
|
|
108
|
-
| mode | ❌ | defalut
|
|
109
|
-
| loop | ❌ | true
|
|
110
|
-
| parallaxScrollingOffset | ❌ | 100
|
|
111
|
-
| parallaxScrollingScale | ❌ | 0.8
|
|
112
|
-
| style | ❌ | {}
|
|
113
|
-
| height | ❌ | '100%'
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
| onProgressChange | ❌ |
|
|
87
|
+
| name | required | default | types | description |
|
|
88
|
+
| ----------------------- | -------- | ------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
89
|
+
| data | ✅ | | T[] | 即将渲染的数据集合 |
|
|
90
|
+
| width | ✅ | | number | 轮播图容器的宽度 |
|
|
91
|
+
| renderItem | ✅ | | (data: T, index: number) => React.ReactNode | 渲染元素的方法 |
|
|
92
|
+
| defaultIndex | ❌ | 0 | number | 默认 index |
|
|
93
|
+
| autoPlay | ❌ | false | boolean | 是否自动播放 |
|
|
94
|
+
| autoPlayReverse | ❌ | false | boolean | 是否倒序自动播放 |
|
|
95
|
+
| autoPlayInterval | ❌ | 1000 | autoPlayInterval | 自动播放的间隔 |
|
|
96
|
+
| mode | ❌ | defalut | 'default'\|'parallax' | 轮播图播放模式,`default`为默认无任何 UI 效果,演示图片使用的`parallax` |
|
|
97
|
+
| loop | ❌ | true | boolean | 是否循环播放 |
|
|
98
|
+
| parallaxScrollingOffset | ❌ | 100 | number | 当使用 mode=`parallax`,这个属性可以控制两侧图片离中间元素的距离 |
|
|
99
|
+
| parallaxScrollingScale | ❌ | 0.8 | number | 当使用 mode=`parallax`,这个属性可以控制两侧图片的缩放比例 |
|
|
100
|
+
| style | ❌ | {} | ViewStyle | 轮播图容器样式 |
|
|
101
|
+
| height | ❌ | '100%' | undefined \| string \| number | 指定轮播图容器高度 |
|
|
102
|
+
| onSnapToItem | ❌ | | (index: number) => void | 切换至另一张轮播图时触发 |
|
|
103
|
+
| onScrollBegin | ❌ | | () => void | 切换动画开始时触发 |
|
|
104
|
+
| onScrollEnd | ❌ | | (previous: number, current: number) => void | 切换动画结束时触发 |
|
|
105
|
+
| panGestureHandlerProps | ❌ | {} | Omit<Partial\<PanGestureHandlerProps\>,'onHandlerStateChange'> | PanGestureHandler props |
|
|
106
|
+
| windowSize | ❌ | 0 | number | 能响应平移手势事件的最大 item 数量,0 表示所有元素都会先响应 |
|
|
107
|
+
| onProgressChange | ❌ | | onProgressChange?: (offsetProgress: number,absoluteProgress: number) => void | 当滚动进度发生变化时触发 `offsetProgress`:总的偏移值 (0 390 780 ...); `absoluteProgress`:转化为 index 的进度变化 (0 1 2 ...) |
|
|
108
|
+
| vertical | ❌ | false | boolean | 将元素垂直布局而不是水平 |
|
|
120
109
|
|
|
121
110
|
## Ref
|
|
122
111
|
|
package/lib/commonjs/Carousel.js
CHANGED
|
@@ -7,8 +7,6 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _react = _interopRequireDefault(require("react"));
|
|
9
9
|
|
|
10
|
-
var _reactNativeGestureHandler = require("react-native-gesture-handler");
|
|
11
|
-
|
|
12
10
|
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
|
|
13
11
|
|
|
14
12
|
var _CarouselItem = require("./CarouselItem");
|
|
@@ -23,22 +21,21 @@ var _useIndexController = require("./hooks/useIndexController");
|
|
|
23
21
|
|
|
24
22
|
var _usePropsErrorBoundary = require("./hooks/usePropsErrorBoundary");
|
|
25
23
|
|
|
24
|
+
var _ScrollViewGesture = require("./ScrollViewGesture");
|
|
25
|
+
|
|
26
|
+
var _useVisibleRanges = require("./hooks/useVisibleRanges");
|
|
27
|
+
|
|
28
|
+
var _reactNative = require("react-native");
|
|
29
|
+
|
|
26
30
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
27
31
|
|
|
28
32
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
29
33
|
|
|
30
34
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
31
35
|
|
|
32
|
-
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
33
|
-
|
|
34
|
-
const defaultSpringConfig = {
|
|
35
|
-
damping: 100
|
|
36
|
-
};
|
|
37
|
-
|
|
38
36
|
function Carousel(props, ref) {
|
|
39
37
|
const {
|
|
40
38
|
defaultIndex = 0,
|
|
41
|
-
height = '100%',
|
|
42
39
|
data: _data = [],
|
|
43
40
|
loop = true,
|
|
44
41
|
mode = 'default',
|
|
@@ -47,37 +44,39 @@ function Carousel(props, ref) {
|
|
|
47
44
|
autoPlayInterval = 1000,
|
|
48
45
|
parallaxScrollingOffset,
|
|
49
46
|
parallaxScrollingScale,
|
|
50
|
-
style,
|
|
47
|
+
style = {},
|
|
51
48
|
panGestureHandlerProps = {},
|
|
52
49
|
renderItem,
|
|
53
50
|
onSnapToItem,
|
|
54
|
-
onProgressChange
|
|
51
|
+
onProgressChange,
|
|
52
|
+
windowSize,
|
|
53
|
+
vertical,
|
|
54
|
+
onScrollBegin,
|
|
55
|
+
onScrollEnd
|
|
55
56
|
} = props;
|
|
56
57
|
(0, _usePropsErrorBoundary.usePropsErrorBoundary)({ ...props,
|
|
57
|
-
defaultIndex,
|
|
58
|
-
height,
|
|
59
58
|
data: _data,
|
|
60
|
-
loop,
|
|
61
59
|
mode,
|
|
62
|
-
|
|
63
|
-
autoPlayReverse,
|
|
64
|
-
autoPlayInterval,
|
|
65
|
-
parallaxScrollingOffset,
|
|
66
|
-
parallaxScrollingScale,
|
|
60
|
+
loop,
|
|
67
61
|
style,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
onSnapToItem,
|
|
72
|
-
onProgressChange
|
|
62
|
+
defaultIndex,
|
|
63
|
+
autoPlayInterval,
|
|
64
|
+
panGestureHandlerProps
|
|
73
65
|
});
|
|
74
|
-
const
|
|
75
|
-
|
|
66
|
+
const width = Math.round(props.width || 0);
|
|
67
|
+
const height = Math.round(props.height || 0);
|
|
68
|
+
const size = vertical ? height : width;
|
|
69
|
+
const layoutStyle = {
|
|
70
|
+
width: width || '100%',
|
|
71
|
+
height: height || '100%'
|
|
76
72
|
};
|
|
77
|
-
const
|
|
78
|
-
const defaultHandlerOffsetX = -Math.abs(defaultIndex * width);
|
|
73
|
+
const defaultHandlerOffsetX = -Math.abs(defaultIndex * size);
|
|
79
74
|
const handlerOffsetX = (0, _reactNativeReanimated.useSharedValue)(defaultHandlerOffsetX);
|
|
80
75
|
|
|
76
|
+
_react.default.useEffect(() => {
|
|
77
|
+
handlerOffsetX.value = defaultHandlerOffsetX;
|
|
78
|
+
}, [vertical, handlerOffsetX, defaultHandlerOffsetX]);
|
|
79
|
+
|
|
81
80
|
const data = _react.default.useMemo(() => {
|
|
82
81
|
if (!loop) return _data;
|
|
83
82
|
|
|
@@ -93,21 +92,21 @@ function Carousel(props, ref) {
|
|
|
93
92
|
}, [_data, loop]);
|
|
94
93
|
|
|
95
94
|
const indexController = (0, _useIndexController.useIndexController)({
|
|
96
|
-
originalLength:
|
|
95
|
+
originalLength: data.length,
|
|
97
96
|
length: data.length,
|
|
98
97
|
handlerOffsetX,
|
|
99
|
-
|
|
98
|
+
size,
|
|
100
99
|
loop,
|
|
101
100
|
onChange: i => onSnapToItem && (0, _reactNativeReanimated.runOnJS)(onSnapToItem)(i)
|
|
102
101
|
});
|
|
103
102
|
const carouselController = (0, _useCarouselController.useCarouselController)({
|
|
104
103
|
loop,
|
|
105
|
-
|
|
104
|
+
size,
|
|
106
105
|
handlerOffsetX,
|
|
107
106
|
indexController,
|
|
108
107
|
disable: !data.length,
|
|
109
|
-
onScrollBegin: () => (0, _reactNativeReanimated.runOnJS)(
|
|
110
|
-
onScrollEnd: () => (0, _reactNativeReanimated.runOnJS)(
|
|
108
|
+
onScrollBegin: () => (0, _reactNativeReanimated.runOnJS)(_onScrollBegin)(),
|
|
109
|
+
onScrollEnd: () => (0, _reactNativeReanimated.runOnJS)(_onScrollEnd)()
|
|
111
110
|
});
|
|
112
111
|
const {
|
|
113
112
|
run,
|
|
@@ -125,40 +124,46 @@ function Carousel(props, ref) {
|
|
|
125
124
|
computedIndex
|
|
126
125
|
} = indexController;
|
|
127
126
|
|
|
128
|
-
const
|
|
129
|
-
|
|
127
|
+
const _onScrollBegin = _react.default.useCallback(() => {
|
|
128
|
+
onScrollBegin === null || onScrollBegin === void 0 ? void 0 : onScrollBegin();
|
|
129
|
+
}, [onScrollBegin]);
|
|
130
130
|
|
|
131
|
+
const scrollViewGestureOnScrollBegin = _react.default.useCallback(() => {
|
|
131
132
|
pause();
|
|
132
|
-
(_props$onScrollBegin = props.onScrollBegin) === null || _props$onScrollBegin === void 0 ? void 0 : _props$onScrollBegin.call(props);
|
|
133
|
-
}, [pause, props]);
|
|
134
133
|
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
_onScrollBegin();
|
|
135
|
+
}, [_onScrollBegin, pause]);
|
|
137
136
|
|
|
138
|
-
|
|
137
|
+
const _onScrollEnd = _react.default.useCallback(() => {
|
|
139
138
|
computedIndex();
|
|
140
|
-
|
|
141
|
-
}, [sharedPreIndex, sharedIndex, computedIndex,
|
|
139
|
+
onScrollEnd === null || onScrollEnd === void 0 ? void 0 : onScrollEnd(sharedPreIndex.current, sharedIndex.current);
|
|
140
|
+
}, [sharedPreIndex, sharedIndex, computedIndex, onScrollEnd]);
|
|
141
|
+
|
|
142
|
+
const scrollViewGestureOnScrollEnd = _react.default.useCallback(() => {
|
|
143
|
+
run();
|
|
144
|
+
|
|
145
|
+
_onScrollEnd();
|
|
146
|
+
}, [_onScrollEnd, run]);
|
|
142
147
|
|
|
143
148
|
const offsetX = (0, _reactNativeReanimated.useDerivedValue)(() => {
|
|
144
|
-
const
|
|
145
|
-
const x = handlerOffsetX.value %
|
|
149
|
+
const totalSize = size * data.length;
|
|
150
|
+
const x = handlerOffsetX.value % totalSize;
|
|
146
151
|
|
|
147
152
|
if (!loop) {
|
|
148
153
|
return handlerOffsetX.value;
|
|
149
154
|
}
|
|
150
155
|
|
|
151
156
|
return isNaN(x) ? 0 : x;
|
|
152
|
-
}, [loop,
|
|
157
|
+
}, [loop, size, data]);
|
|
153
158
|
(0, _reactNativeReanimated.useAnimatedReaction)(() => offsetX.value, value => {
|
|
154
|
-
let absoluteProgress = Math.abs(value /
|
|
159
|
+
let absoluteProgress = Math.abs(value / size);
|
|
155
160
|
|
|
156
161
|
if (value > 0) {
|
|
157
162
|
absoluteProgress = data.length - absoluteProgress;
|
|
158
163
|
}
|
|
159
164
|
|
|
160
165
|
!!onProgressChange && (0, _reactNativeReanimated.runOnJS)(onProgressChange)(value, absoluteProgress);
|
|
161
|
-
}, [onProgressChange,
|
|
166
|
+
}, [onProgressChange, props.children]);
|
|
162
167
|
|
|
163
168
|
const next = _react.default.useCallback(() => {
|
|
164
169
|
return carouselController.next();
|
|
@@ -176,64 +181,6 @@ function Carousel(props, ref) {
|
|
|
176
181
|
carouselController.to(i, animated);
|
|
177
182
|
}, [carouselController]);
|
|
178
183
|
|
|
179
|
-
const animatedListScrollHandler = (0, _reactNativeReanimated.useAnimatedGestureHandler)({
|
|
180
|
-
onStart: (_, ctx) => {
|
|
181
|
-
(0, _reactNativeReanimated.runOnJS)(pause)();
|
|
182
|
-
(0, _reactNativeReanimated.runOnJS)(onScrollBegin)();
|
|
183
|
-
(0, _reactNativeReanimated.cancelAnimation)(handlerOffsetX);
|
|
184
|
-
ctx.currentContentOffsetX = handlerOffsetX.value;
|
|
185
|
-
ctx.start = true;
|
|
186
|
-
},
|
|
187
|
-
onActive: (e, ctx) => {
|
|
188
|
-
const {
|
|
189
|
-
translationX
|
|
190
|
-
} = e;
|
|
191
|
-
|
|
192
|
-
if (!loop && (handlerOffsetX.value >= 0 || handlerOffsetX.value <= -(data.length - 1) * width)) {
|
|
193
|
-
handlerOffsetX.value = ctx.currentContentOffsetX + translationX / 2;
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
handlerOffsetX.value = ctx.currentContentOffsetX + translationX;
|
|
198
|
-
},
|
|
199
|
-
onEnd: e => {
|
|
200
|
-
function _withAnimationCallback(num) {
|
|
201
|
-
return (0, _reactNativeReanimated.withSpring)(num, Object.assign({}, timingConfig, {
|
|
202
|
-
velocity: e.velocityX
|
|
203
|
-
}), isFinished => {
|
|
204
|
-
if (isFinished) {
|
|
205
|
-
(0, _reactNativeReanimated.runOnJS)(onScrollEnd)();
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const page = Math.round(handlerOffsetX.value / width);
|
|
211
|
-
const velocityPage = Math.round((handlerOffsetX.value + e.velocityX) / width);
|
|
212
|
-
let pageWithVelocity = Math.min(page + 1, Math.max(page - 1, velocityPage));
|
|
213
|
-
|
|
214
|
-
if (!loop) {
|
|
215
|
-
pageWithVelocity = Math.max(-(data.length - 1), Math.min(0, pageWithVelocity));
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (loop) {
|
|
219
|
-
handlerOffsetX.value = _withAnimationCallback(pageWithVelocity * width);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (handlerOffsetX.value >= 0) {
|
|
224
|
-
handlerOffsetX.value = _withAnimationCallback(0);
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
if (handlerOffsetX.value <= -(data.length - 1) * width) {
|
|
229
|
-
handlerOffsetX.value = _withAnimationCallback(-(data.length - 1) * width);
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
handlerOffsetX.value = _withAnimationCallback(pageWithVelocity * width);
|
|
234
|
-
}
|
|
235
|
-
}, [loop, data, onScrollBegin, onScrollEnd]);
|
|
236
|
-
|
|
237
184
|
_react.default.useImperativeHandle(ref, () => ({
|
|
238
185
|
next,
|
|
239
186
|
prev,
|
|
@@ -241,6 +188,13 @@ function Carousel(props, ref) {
|
|
|
241
188
|
goToIndex
|
|
242
189
|
}), [getCurrentIndex, goToIndex, next, prev]);
|
|
243
190
|
|
|
191
|
+
const visibleRanges = (0, _useVisibleRanges.useVisibleRanges)({
|
|
192
|
+
total: data.length,
|
|
193
|
+
viewSize: size,
|
|
194
|
+
translation: handlerOffsetX,
|
|
195
|
+
windowSize
|
|
196
|
+
});
|
|
197
|
+
|
|
244
198
|
const renderLayout = _react.default.useCallback((item, i) => {
|
|
245
199
|
switch (mode) {
|
|
246
200
|
case 'parallax':
|
|
@@ -249,10 +203,13 @@ function Carousel(props, ref) {
|
|
|
249
203
|
parallaxScrollingScale: parallaxScrollingScale,
|
|
250
204
|
data: data,
|
|
251
205
|
width: width,
|
|
206
|
+
height: height,
|
|
252
207
|
handlerOffsetX: offsetX,
|
|
253
208
|
index: i,
|
|
254
209
|
key: i,
|
|
255
|
-
loop: loop
|
|
210
|
+
loop: loop,
|
|
211
|
+
visibleRanges: visibleRanges,
|
|
212
|
+
vertical: vertical
|
|
256
213
|
}, renderItem(item, i));
|
|
257
214
|
|
|
258
215
|
default:
|
|
@@ -263,25 +220,44 @@ function Carousel(props, ref) {
|
|
|
263
220
|
handlerOffsetX: offsetX,
|
|
264
221
|
index: i,
|
|
265
222
|
key: i,
|
|
266
|
-
loop: loop
|
|
223
|
+
loop: loop,
|
|
224
|
+
visibleRanges: visibleRanges,
|
|
225
|
+
vertical: vertical
|
|
267
226
|
}, renderItem(item, i));
|
|
268
227
|
}
|
|
269
|
-
}, [loop, mode, data,
|
|
270
|
-
|
|
271
|
-
return /*#__PURE__*/_react.default.createElement(
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
228
|
+
}, [loop, mode, data, offsetX, parallaxScrollingOffset, parallaxScrollingScale, renderItem, visibleRanges, vertical, width, height]);
|
|
229
|
+
|
|
230
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
231
|
+
style: [styles.container, layoutStyle, style]
|
|
232
|
+
}, /*#__PURE__*/_react.default.createElement(_ScrollViewGesture.ScrollViewGesture, {
|
|
233
|
+
pagingEnabled: true,
|
|
234
|
+
vertical: vertical,
|
|
235
|
+
infinite: loop,
|
|
236
|
+
translation: handlerOffsetX,
|
|
237
|
+
style: style,
|
|
238
|
+
max: data.length * size,
|
|
239
|
+
size: size,
|
|
240
|
+
panGestureHandlerProps: panGestureHandlerProps,
|
|
241
|
+
onScrollBegin: scrollViewGestureOnScrollBegin,
|
|
242
|
+
onScrollEnd: scrollViewGestureOnScrollEnd
|
|
243
|
+
}, /*#__PURE__*/_react.default.createElement(_reactNativeReanimated.default.View, {
|
|
244
|
+
style: [styles.container, layoutStyle, style, vertical ? styles.itemsVertical : styles.itemsHorizontal]
|
|
245
|
+
}, data.map(renderLayout))));
|
|
282
246
|
}
|
|
283
247
|
|
|
284
248
|
var _default = /*#__PURE__*/_react.default.forwardRef(Carousel);
|
|
285
249
|
|
|
286
250
|
exports.default = _default;
|
|
251
|
+
|
|
252
|
+
const styles = _reactNative.StyleSheet.create({
|
|
253
|
+
container: {
|
|
254
|
+
overflow: 'hidden'
|
|
255
|
+
},
|
|
256
|
+
itemsHorizontal: {
|
|
257
|
+
flexDirection: 'row'
|
|
258
|
+
},
|
|
259
|
+
itemsVertical: {
|
|
260
|
+
flexDirection: 'column'
|
|
261
|
+
}
|
|
262
|
+
});
|
|
287
263
|
//# sourceMappingURL=Carousel.js.map
|