react-native-reanimated-carousel 1.0.8 → 1.0.9
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 +11 -25
- package/README.zh-CN.md +14 -25
- package/lib/commonjs/Carousel.js +16 -4
- package/lib/commonjs/Carousel.js.map +1 -1
- package/lib/commonjs/CarouselItem.js +3 -2
- package/lib/commonjs/CarouselItem.js.map +1 -1
- package/lib/commonjs/hooks/useOffsetX.js +11 -2
- package/lib/commonjs/hooks/useOffsetX.js.map +1 -1
- package/lib/commonjs/hooks/useVisibleRanges.js +42 -0
- package/lib/commonjs/hooks/useVisibleRanges.js.map +1 -0
- package/lib/commonjs/layouts/ParallaxLayout.js +3 -2
- package/lib/commonjs/layouts/ParallaxLayout.js.map +1 -1
- package/lib/commonjs/utils/log.js +2 -2
- package/lib/commonjs/utils/log.js.map +1 -1
- package/lib/module/Carousel.js +14 -4
- package/lib/module/Carousel.js.map +1 -1
- package/lib/module/CarouselItem.js +3 -2
- package/lib/module/CarouselItem.js.map +1 -1
- package/lib/module/hooks/useOffsetX.js +11 -2
- package/lib/module/hooks/useOffsetX.js.map +1 -1
- package/lib/module/hooks/useVisibleRanges.js +34 -0
- package/lib/module/hooks/useVisibleRanges.js.map +1 -0
- package/lib/module/layouts/ParallaxLayout.js +3 -2
- package/lib/module/layouts/ParallaxLayout.js.map +1 -1
- package/lib/module/utils/log.js +2 -2
- package/lib/module/utils/log.js.map +1 -1
- package/lib/typescript/Carousel.d.ts +7 -0
- package/lib/typescript/CarouselItem.d.ts +2 -0
- package/lib/typescript/hooks/useOffsetX.d.ts +2 -1
- package/lib/typescript/hooks/useVisibleRanges.d.ts +11 -0
- package/lib/typescript/layouts/ParallaxLayout.d.ts +2 -0
- package/lib/typescript/utils/log.d.ts +1 -1
- package/package.json +1 -1
- package/src/Carousel.tsx +19 -0
- package/src/CarouselItem.tsx +13 -7
- package/src/hooks/useOffsetX.ts +10 -2
- package/src/hooks/useVisibleRanges.tsx +42 -0
- package/src/layouts/ParallaxLayout.tsx +13 -7
- package/src/utils/log.ts +2 -2
package/README.md
CHANGED
|
@@ -16,23 +16,15 @@ English | [简体中文](./README.zh-CN.md)
|
|
|
16
16
|
|
|
17
17
|
<br/>
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## ReactNative community's best use of the carousel component! 🎉🎉🎉
|
|
20
20
|
|
|
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)
|
|
21
|
+
- 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...
|
|
22
|
+
- **Simple**、**Infinitely scrolling very smooth**、**Fully implemented using Reanimated 2!**
|
|
28
23
|
|
|
29
24
|
## Reason
|
|
30
25
|
|
|
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.
|
|
26
|
+
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.[Try it with SNACK](https://snack.expo.dev/@zhaodonghao586/simple-carousel)
|
|
34
27
|
|
|
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
|
|
|
37
29
|
<p align="center">
|
|
38
30
|
Use react-native-snap-carousel for quick swiping,you can see caton clearly when you reach the junction.(gif 4.6mb)
|
|
@@ -72,28 +64,21 @@ If use EXPO managed workflow please ensure that the version is greater than 41.B
|
|
|
72
64
|
|
|
73
65
|
## Usage
|
|
74
66
|
|
|
75
|
-
```
|
|
67
|
+
```tsx
|
|
76
68
|
import Carousel from 'react-native-reanimated-carousel';
|
|
77
69
|
|
|
78
|
-
// ...
|
|
79
|
-
|
|
80
70
|
<Carousel<{ color: string }>
|
|
81
|
-
width={width}
|
|
71
|
+
width={ width }
|
|
82
72
|
data={[{ color: 'red' }, { color: 'purple' }, { color: 'yellow' }]}
|
|
83
73
|
renderItem={({ color }) => {
|
|
84
|
-
return
|
|
85
|
-
<View
|
|
86
|
-
style={{
|
|
87
|
-
backgroundColor: color,
|
|
88
|
-
justifyContent: 'center',
|
|
89
|
-
flex: 1,
|
|
90
|
-
}}
|
|
91
|
-
/>
|
|
92
|
-
);
|
|
74
|
+
return <View style={{ backgroundColor: color, flex: 1}}/>
|
|
93
75
|
}}
|
|
94
76
|
/>;
|
|
95
77
|
```
|
|
96
78
|
|
|
79
|
+
## Optimizing
|
|
80
|
+
- 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)
|
|
81
|
+
|
|
97
82
|
## Props
|
|
98
83
|
|
|
99
84
|
| name | required | default | types | description |
|
|
@@ -116,6 +101,7 @@ import Carousel from 'react-native-reanimated-carousel';
|
|
|
116
101
|
| onScrollBegin | ❌ | | () => void | Callback fired when scroll begin |
|
|
117
102
|
| onScrollEnd | ❌ | | (previous: number, current: number) => void | Callback fired when scroll end |
|
|
118
103
|
| panGestureHandlerProps | ❌ | {} | Omit<Partial\<PanGestureHandlerProps\>,'onHandlerStateChange'> | PanGestureHandler props |
|
|
104
|
+
| 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
|
|
119
105
|
| 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 ...) |
|
|
120
106
|
|
|
121
107
|
## Ref
|
package/README.zh-CN.md
CHANGED
|
@@ -16,23 +16,17 @@
|
|
|
16
16
|
|
|
17
17
|
<br/>
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## ReactNative社区最好用的轮播图组件! 🎉🎉🎉
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
- 完全解决了`react-native-snap-carousel`的[问题](https://github.com/meliorence/react-native-snap-carousel/issues/632)! 更多样式与API正在开发中...
|
|
22
|
+
- **易用**、**无限滚动**、**完全使用 Reanimated2 实现**
|
|
22
23
|
|
|
23
|
-
更新:
|
|
24
24
|
|
|
25
|
-
- 重构了部分逻辑,滑动动画更加流畅、自然
|
|
26
|
-
- timingConfig -> springConfig (此配置不再支持对`duration`属性的配置)
|
|
27
|
-
- [...](https://github.com/dohooo/react-native-reanimated-carousel/releases/tag/v1.0.0)
|
|
28
25
|
|
|
26
|
+
|
|
29
27
|
## 原因
|
|
28
|
+
常见的无限滚动轮播图,在快速滑动时会出现卡住的情况,这是因为实现方式而导致的问题。这个组件用了不同的方式来实现,解决了这个问题,这就是创建这个库的原因。[在 SNACK 上尝试](https://snack.expo.dev/@zhaodonghao586/simple-carousel)
|
|
30
29
|
|
|
31
|
-
🎉 **完全解决了`react-native-snap-carousel`的[这个问题](https://github.com/meliorence/react-native-snap-carousel/issues/632)! 易用、无限滚动、完全使用 Reanimated2 实现**
|
|
32
|
-
|
|
33
|
-
> 常见的无限滚动轮播图,在快速滑动时会出现卡住的情况,这是因为实现方式而导致的问题。这个组件用了不同的方式来实现,解决了这个问题,这就是创建这个库的原因。
|
|
34
|
-
|
|
35
|
-
> 目前他只满足了我工作上的需要,欢迎大家的 ISSUES/PR。[在 SNACK 上尝试](https://snack.expo.dev/@zhaodonghao586/simple-carousel)
|
|
36
30
|
|
|
37
31
|
<p align="center">
|
|
38
32
|
使用react-native-snap-carousel快速滑动,当到连接处时可以看清楚的看到卡顿。(gif 4.6mb)
|
|
@@ -72,28 +66,22 @@ 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
|
-
width={width}
|
|
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
|
+
- 当渲染大量元素时,可使用`windowSize`属性,来控制当前元素的两侧渲染数量,默认为全量渲染。经测试不加此属性,渲染200个空view时会出现掉帧情况,设置此属性后渲染1000个空view依旧流畅。(具体数量与测试的手机型号相关)
|
|
83
|
+
|
|
84
|
+
|
|
97
85
|
## Props
|
|
98
86
|
|
|
99
87
|
| name | required | default | types | description |
|
|
@@ -115,7 +103,8 @@ import Carousel from 'react-native-reanimated-carousel';
|
|
|
115
103
|
| onSnapToItem | ❌ | | (index: number) => void | 切换至另一张轮播图时触发 |
|
|
116
104
|
| onScrollBegin | ❌ | | () => void | 切换动画开始时触发 |
|
|
117
105
|
| onScrollEnd | ❌ | | (previous: number, current: number) => void | 切换动画结束时触发 |
|
|
118
|
-
| panGestureHandlerProps | ❌ | {} | Omit<Partial\<PanGestureHandlerProps\>,'onHandlerStateChange'> | PanGestureHandler props
|
|
106
|
+
| panGestureHandlerProps | ❌ | {} | Omit<Partial\<PanGestureHandlerProps\>,'onHandlerStateChange'> | PanGestureHandler props
|
|
107
|
+
| windowSize | ❌ | 0 | number | 能响应平移手势事件的最大item数量,0表示所有元素都会先响应 |
|
|
119
108
|
| onProgressChange | ❌ | | onProgressChange?: (offsetProgress: number,absoluteProgress: number) => void | 当滚动进度发生变化时触发 `offsetProgress`:总的偏移值 (0 390 780 ...); `absoluteProgress`:转化为 index 的进度变化 (0 1 2 ...) |
|
|
120
109
|
|
|
121
110
|
## Ref
|
package/lib/commonjs/Carousel.js
CHANGED
|
@@ -23,6 +23,8 @@ var _useIndexController = require("./hooks/useIndexController");
|
|
|
23
23
|
|
|
24
24
|
var _usePropsErrorBoundary = require("./hooks/usePropsErrorBoundary");
|
|
25
25
|
|
|
26
|
+
var _useVisibleRanges = require("./hooks/useVisibleRanges");
|
|
27
|
+
|
|
26
28
|
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
29
|
|
|
28
30
|
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; }
|
|
@@ -51,7 +53,8 @@ function Carousel(props, ref) {
|
|
|
51
53
|
panGestureHandlerProps = {},
|
|
52
54
|
renderItem,
|
|
53
55
|
onSnapToItem,
|
|
54
|
-
onProgressChange
|
|
56
|
+
onProgressChange,
|
|
57
|
+
windowSize
|
|
55
58
|
} = props;
|
|
56
59
|
(0, _usePropsErrorBoundary.usePropsErrorBoundary)({ ...props,
|
|
57
60
|
defaultIndex,
|
|
@@ -241,6 +244,13 @@ function Carousel(props, ref) {
|
|
|
241
244
|
goToIndex
|
|
242
245
|
}), [getCurrentIndex, goToIndex, next, prev]);
|
|
243
246
|
|
|
247
|
+
const visibleRanges = (0, _useVisibleRanges.useVisibleRanges)({
|
|
248
|
+
total: data.length,
|
|
249
|
+
viewSize: width,
|
|
250
|
+
translation: handlerOffsetX,
|
|
251
|
+
windowSize
|
|
252
|
+
});
|
|
253
|
+
|
|
244
254
|
const renderLayout = _react.default.useCallback((item, i) => {
|
|
245
255
|
switch (mode) {
|
|
246
256
|
case 'parallax':
|
|
@@ -252,7 +262,8 @@ function Carousel(props, ref) {
|
|
|
252
262
|
handlerOffsetX: offsetX,
|
|
253
263
|
index: i,
|
|
254
264
|
key: i,
|
|
255
|
-
loop: loop
|
|
265
|
+
loop: loop,
|
|
266
|
+
visibleRanges: visibleRanges
|
|
256
267
|
}, renderItem(item, i));
|
|
257
268
|
|
|
258
269
|
default:
|
|
@@ -263,10 +274,11 @@ function Carousel(props, ref) {
|
|
|
263
274
|
handlerOffsetX: offsetX,
|
|
264
275
|
index: i,
|
|
265
276
|
key: i,
|
|
266
|
-
loop: loop
|
|
277
|
+
loop: loop,
|
|
278
|
+
visibleRanges: visibleRanges
|
|
267
279
|
}, renderItem(item, i));
|
|
268
280
|
}
|
|
269
|
-
}, [loop, mode, data, height, offsetX, parallaxScrollingOffset, parallaxScrollingScale, width, renderItem]);
|
|
281
|
+
}, [loop, mode, data, height, offsetX, parallaxScrollingOffset, parallaxScrollingScale, width, renderItem, visibleRanges]);
|
|
270
282
|
|
|
271
283
|
return /*#__PURE__*/_react.default.createElement(_reactNativeGestureHandler.PanGestureHandler, _extends({}, panGestureHandlerProps, {
|
|
272
284
|
onGestureEvent: animatedListScrollHandler
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["Carousel.tsx"],"names":["defaultSpringConfig","damping","Carousel","props","ref","defaultIndex","height","data","_data","loop","mode","autoPlay","autoPlayReverse","autoPlayInterval","parallaxScrollingOffset","parallaxScrollingScale","style","panGestureHandlerProps","renderItem","onSnapToItem","onProgressChange","timingConfig","springConfig","width","Math","round","defaultHandlerOffsetX","abs","handlerOffsetX","React","useMemo","length","indexController","originalLength","onChange","i","carouselController","disable","onScrollBegin","onScrollEnd","run","pause","index","sharedPreIndex","sharedIndex","computedIndex","useCallback","current","offsetX","totalWidth","x","value","isNaN","absoluteProgress","next","prev","getCurrentIndex","goToIndex","animated","to","animatedListScrollHandler","onStart","_","ctx","currentContentOffsetX","start","onActive","e","translationX","onEnd","_withAnimationCallback","num","Object","assign","velocity","velocityX","isFinished","page","velocityPage","pageWithVelocity","min","max","useImperativeHandle","renderLayout","item","flexDirection","position","map","forwardRef"],"mappings":"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","sourcesContent":["import React from 'react';\nimport type { FlexStyle, ViewStyle } from 'react-native';\nimport {\n PanGestureHandler,\n PanGestureHandlerProps,\n PanGestureHandlerGestureEvent,\n} from 'react-native-gesture-handler';\nimport Animated, {\n cancelAnimation,\n runOnJS,\n useAnimatedGestureHandler,\n useAnimatedReaction,\n useDerivedValue,\n useSharedValue,\n withSpring,\n} from 'react-native-reanimated';\nimport { CarouselItem } from './CarouselItem';\nimport type { TMode } from './layouts';\nimport { ParallaxLayout } from './layouts/index';\nimport { useCarouselController } from './hooks/useCarouselController';\nimport { useAutoPlay } from './hooks/useAutoPlay';\nimport { useIndexController } from './hooks/useIndexController';\nimport { usePropsErrorBoundary } from './hooks/usePropsErrorBoundary';\n\nconst defaultSpringConfig: Animated.WithSpringConfig = {\n damping: 100,\n};\nexport interface ICarouselProps<T extends unknown> {\n ref?: React.Ref<ICarouselInstance>;\n /**\n * Carousel loop playback.\n * @default true\n */\n loop?: boolean;\n /**\n * Carousel Animated transitions.\n * @default 'default'\n */\n mode?: TMode;\n /**\n * Specified carousel container width.\n */\n width: number;\n /**\n * Specified carousel container height.\n * @default '100%'\n */\n height?: FlexStyle['height'];\n /**\n * Carousel items data set.\n */\n data: T[];\n /**\n * Default index\n * @default 0\n */\n defaultIndex?: number;\n /**\n * Auto play\n */\n autoPlay?: boolean;\n /**\n * Auto play\n * @description reverse playback\n */\n autoPlayReverse?: boolean;\n /**\n * Auto play\n * @description playback interval\n */\n autoPlayInterval?: number;\n /**\n * Carousel container style\n */\n style?: ViewStyle;\n /**\n * When use 'default' Layout props,this prop can be control prev/next item offset.\n * @default 100\n */\n parallaxScrollingOffset?: number;\n /**\n * When use 'default' Layout props,this prop can be control prev/next item offset.\n * @default 0.8\n */\n parallaxScrollingScale?: number;\n /**\n * Sping config of translation animated\n */\n springConfig?: Animated.WithSpringConfig;\n /**\n * PanGestureHandler props\n */\n panGestureHandlerProps?: Omit<\n Partial<PanGestureHandlerProps>,\n 'onHandlerStateChange'\n >;\n /**\n * Render carousel item.\n */\n renderItem: (data: T, index: number) => React.ReactNode;\n /**\n * Callback fired when navigating to an item\n */\n onSnapToItem?: (index: number) => void;\n /**\n * On scroll begin\n */\n onScrollBegin?: () => void;\n /**\n * On scroll end\n */\n onScrollEnd?: (previous: number, current: number) => void;\n /**\n * On progress change\n * @param offsetProgress Total of offset distance (0 390 780 ...)\n * @param absoluteProgress Convert to index (0 1 2 ...)\n */\n onProgressChange?: (\n offsetProgress: number,\n absoluteProgress: number\n ) => void;\n}\n\nexport interface ICarouselInstance {\n /**\n * Play the last one\n */\n prev: () => void;\n /**\n * Play the next one\n */\n next: () => void;\n /**\n * Get current item index\n */\n getCurrentIndex: () => number;\n /**\n * Go to index\n */\n goToIndex: (index: number, animated?: boolean) => void;\n}\n\nfunction Carousel<T extends unknown = any>(\n props: ICarouselProps<T>,\n ref: React.Ref<ICarouselInstance>\n) {\n const {\n defaultIndex = 0,\n height = '100%',\n data: _data = [],\n loop = true,\n mode = 'default',\n autoPlay,\n autoPlayReverse,\n autoPlayInterval = 1000,\n parallaxScrollingOffset,\n parallaxScrollingScale,\n style,\n panGestureHandlerProps = {},\n renderItem,\n onSnapToItem,\n onProgressChange,\n } = props;\n\n usePropsErrorBoundary({\n ...props,\n defaultIndex,\n height,\n data: _data,\n loop,\n mode,\n autoPlay,\n autoPlayReverse,\n autoPlayInterval,\n parallaxScrollingOffset,\n parallaxScrollingScale,\n style,\n panGestureHandlerProps,\n // @ts-ignore\n renderItem,\n onSnapToItem,\n onProgressChange,\n });\n\n const timingConfig = {\n ...defaultSpringConfig,\n ...props.springConfig,\n };\n const width = Math.round(props.width);\n const defaultHandlerOffsetX = -Math.abs(defaultIndex * width);\n const handlerOffsetX = useSharedValue<number>(defaultHandlerOffsetX);\n const data = React.useMemo<T[]>(() => {\n if (!loop) return _data;\n\n if (_data.length === 1) {\n return [_data[0], _data[0], _data[0]];\n }\n\n if (_data.length === 2) {\n return [_data[0], _data[1], _data[0], _data[1]];\n }\n\n return _data;\n }, [_data, loop]);\n\n const indexController = useIndexController({\n originalLength: _data.length,\n length: data.length,\n handlerOffsetX,\n width,\n loop,\n onChange: (i) => onSnapToItem && runOnJS(onSnapToItem)(i),\n });\n\n const carouselController = useCarouselController({\n loop,\n width,\n handlerOffsetX,\n indexController,\n disable: !data.length,\n onScrollBegin: () => runOnJS(onScrollBegin)(),\n onScrollEnd: () => runOnJS(onScrollEnd)(),\n });\n\n const { run, pause } = useAutoPlay({\n autoPlay,\n autoPlayInterval,\n autoPlayReverse,\n carouselController,\n });\n\n const { index, sharedPreIndex, sharedIndex, computedIndex } =\n indexController;\n\n const onScrollBegin = React.useCallback(() => {\n pause();\n props.onScrollBegin?.();\n }, [pause, props]);\n\n const onScrollEnd = React.useCallback(() => {\n run();\n computedIndex();\n props.onScrollEnd?.(sharedPreIndex.current, sharedIndex.current);\n }, [sharedPreIndex, sharedIndex, computedIndex, props, run]);\n\n const offsetX = useDerivedValue(() => {\n const totalWidth = width * data.length;\n const x = handlerOffsetX.value % totalWidth;\n\n if (!loop) {\n return handlerOffsetX.value;\n }\n return isNaN(x) ? 0 : x;\n }, [loop, width, data]);\n\n useAnimatedReaction(\n () => offsetX.value,\n (value) => {\n let absoluteProgress = Math.abs(value / width);\n if (value > 0) {\n absoluteProgress = data.length - absoluteProgress;\n }\n !!onProgressChange &&\n runOnJS(onProgressChange)(value, absoluteProgress);\n },\n [onProgressChange, data]\n );\n\n const next = React.useCallback(() => {\n return carouselController.next();\n }, [carouselController]);\n\n const prev = React.useCallback(() => {\n return carouselController.prev();\n }, [carouselController]);\n\n const getCurrentIndex = React.useCallback(() => {\n return index.value;\n }, [index]);\n\n const goToIndex = React.useCallback(\n (i: number, animated?: boolean) => {\n carouselController.to(i, animated);\n },\n [carouselController]\n );\n\n const animatedListScrollHandler =\n useAnimatedGestureHandler<PanGestureHandlerGestureEvent>(\n {\n onStart: (_, ctx: any) => {\n runOnJS(pause)();\n runOnJS(onScrollBegin)();\n cancelAnimation(handlerOffsetX);\n ctx.currentContentOffsetX = handlerOffsetX.value;\n ctx.start = true;\n },\n onActive: (e, ctx: any) => {\n const { translationX } = e;\n if (\n !loop &&\n (handlerOffsetX.value >= 0 ||\n handlerOffsetX.value <= -(data.length - 1) * width)\n ) {\n handlerOffsetX.value =\n ctx.currentContentOffsetX + translationX / 2;\n return;\n }\n handlerOffsetX.value =\n ctx.currentContentOffsetX + translationX;\n },\n onEnd: (e) => {\n function _withAnimationCallback(num: number) {\n return withSpring(\n num,\n Object.assign({}, timingConfig, {\n velocity: e.velocityX,\n }),\n (isFinished) => {\n if (isFinished) {\n runOnJS(onScrollEnd)();\n }\n }\n );\n }\n\n const page = Math.round(handlerOffsetX.value / width);\n\n const velocityPage = Math.round(\n (handlerOffsetX.value + e.velocityX) / width\n );\n\n let pageWithVelocity = Math.min(\n page + 1,\n Math.max(page - 1, velocityPage)\n );\n\n if (!loop) {\n pageWithVelocity = Math.max(\n -(data.length - 1),\n Math.min(0, pageWithVelocity)\n );\n }\n\n if (loop) {\n handlerOffsetX.value = _withAnimationCallback(\n pageWithVelocity * width\n );\n return;\n }\n if (handlerOffsetX.value >= 0) {\n handlerOffsetX.value = _withAnimationCallback(0);\n return;\n }\n\n if (handlerOffsetX.value <= -(data.length - 1) * width) {\n handlerOffsetX.value = _withAnimationCallback(\n -(data.length - 1) * width\n );\n return;\n }\n\n handlerOffsetX.value = _withAnimationCallback(\n pageWithVelocity * width\n );\n },\n },\n [loop, data, onScrollBegin, onScrollEnd]\n );\n\n React.useImperativeHandle(\n ref,\n () => ({\n next,\n prev,\n getCurrentIndex,\n goToIndex,\n }),\n [getCurrentIndex, goToIndex, next, prev]\n );\n\n const renderLayout = React.useCallback(\n (item: T, i: number) => {\n switch (mode) {\n case 'parallax':\n return (\n <ParallaxLayout\n parallaxScrollingOffset={parallaxScrollingOffset}\n parallaxScrollingScale={parallaxScrollingScale}\n data={data}\n width={width}\n handlerOffsetX={offsetX}\n index={i}\n key={i}\n loop={loop}\n >\n {renderItem(item, i)}\n </ParallaxLayout>\n );\n default:\n return (\n <CarouselItem\n data={data}\n width={width}\n height={height}\n handlerOffsetX={offsetX}\n index={i}\n key={i}\n loop={loop}\n >\n {renderItem(item, i)}\n </CarouselItem>\n );\n }\n },\n [\n loop,\n mode,\n data,\n height,\n offsetX,\n parallaxScrollingOffset,\n parallaxScrollingScale,\n width,\n renderItem,\n ]\n );\n\n return (\n <PanGestureHandler\n {...panGestureHandlerProps}\n onGestureEvent={animatedListScrollHandler}\n >\n <Animated.View\n // eslint-disable-next-line react-native/no-inline-styles\n style={{\n ...style,\n width,\n height,\n flexDirection: 'row',\n position: 'relative',\n }}\n >\n {data.map(renderLayout)}\n </Animated.View>\n </PanGestureHandler>\n );\n}\n\nexport default React.forwardRef(Carousel) as typeof Carousel;\n"]}
|
|
1
|
+
{"version":3,"sources":["Carousel.tsx"],"names":["defaultSpringConfig","damping","Carousel","props","ref","defaultIndex","height","data","_data","loop","mode","autoPlay","autoPlayReverse","autoPlayInterval","parallaxScrollingOffset","parallaxScrollingScale","style","panGestureHandlerProps","renderItem","onSnapToItem","onProgressChange","windowSize","timingConfig","springConfig","width","Math","round","defaultHandlerOffsetX","abs","handlerOffsetX","React","useMemo","length","indexController","originalLength","onChange","i","carouselController","disable","onScrollBegin","onScrollEnd","run","pause","index","sharedPreIndex","sharedIndex","computedIndex","useCallback","current","offsetX","totalWidth","x","value","isNaN","absoluteProgress","next","prev","getCurrentIndex","goToIndex","animated","to","animatedListScrollHandler","onStart","_","ctx","currentContentOffsetX","start","onActive","e","translationX","onEnd","_withAnimationCallback","num","Object","assign","velocity","velocityX","isFinished","page","velocityPage","pageWithVelocity","min","max","useImperativeHandle","visibleRanges","total","viewSize","translation","renderLayout","item","flexDirection","position","map","forwardRef"],"mappings":"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","sourcesContent":["import React from 'react';\nimport type { FlexStyle, ViewStyle } from 'react-native';\nimport {\n PanGestureHandler,\n PanGestureHandlerProps,\n PanGestureHandlerGestureEvent,\n} from 'react-native-gesture-handler';\nimport Animated, {\n cancelAnimation,\n runOnJS,\n useAnimatedGestureHandler,\n useAnimatedReaction,\n useDerivedValue,\n useSharedValue,\n withSpring,\n} from 'react-native-reanimated';\nimport { CarouselItem } from './CarouselItem';\nimport type { TMode } from './layouts';\nimport { ParallaxLayout } from './layouts/index';\nimport { useCarouselController } from './hooks/useCarouselController';\nimport { useAutoPlay } from './hooks/useAutoPlay';\nimport { useIndexController } from './hooks/useIndexController';\nimport { usePropsErrorBoundary } from './hooks/usePropsErrorBoundary';\nimport { useVisibleRanges } from './hooks/useVisibleRanges';\n\nconst defaultSpringConfig: Animated.WithSpringConfig = {\n damping: 100,\n};\nexport interface ICarouselProps<T extends unknown> {\n ref?: React.Ref<ICarouselInstance>;\n /**\n * Carousel loop playback.\n * @default true\n */\n loop?: boolean;\n /**\n * Carousel Animated transitions.\n * @default 'default'\n */\n mode?: TMode;\n /**\n * Specified carousel container width.\n */\n width: number;\n /**\n * Specified carousel container height.\n * @default '100%'\n */\n height?: FlexStyle['height'];\n /**\n * Carousel items data set.\n */\n data: T[];\n /**\n * Default index\n * @default 0\n */\n defaultIndex?: number;\n /**\n * Auto play\n */\n autoPlay?: boolean;\n /**\n * Auto play\n * @description reverse playback\n */\n autoPlayReverse?: boolean;\n /**\n * Auto play\n * @description playback interval\n */\n autoPlayInterval?: number;\n /**\n * Carousel container style\n */\n style?: ViewStyle;\n /**\n * When use 'default' Layout props,this prop can be control prev/next item offset.\n * @default 100\n */\n parallaxScrollingOffset?: number;\n /**\n * When use 'default' Layout props,this prop can be control prev/next item offset.\n * @default 0.8\n */\n parallaxScrollingScale?: number;\n /**\n * Sping config of translation animated\n */\n springConfig?: Animated.WithSpringConfig;\n /**\n * PanGestureHandler props\n */\n panGestureHandlerProps?: Omit<\n Partial<PanGestureHandlerProps>,\n 'onHandlerStateChange'\n >;\n /**\n * Determines the maximum number of items will respond to pan gesture events,\n * windowSize={11} will active visible item plus up to 5 items above and 5 below the viewpor,\n * Reducing this number will reduce the calculation of the animation value and may improve performance.\n * @default 0 all items will respond to pan gesture events.\n */\n windowSize?: number;\n /**\n * Render carousel item.\n */\n renderItem: (data: T, index: number) => React.ReactNode;\n /**\n * Callback fired when navigating to an item\n */\n onSnapToItem?: (index: number) => void;\n /**\n * On scroll begin\n */\n onScrollBegin?: () => void;\n /**\n * On scroll end\n */\n onScrollEnd?: (previous: number, current: number) => void;\n /**\n * On progress change\n * @param offsetProgress Total of offset distance (0 390 780 ...)\n * @param absoluteProgress Convert to index (0 1 2 ...)\n */\n onProgressChange?: (\n offsetProgress: number,\n absoluteProgress: number\n ) => void;\n}\n\nexport interface ICarouselInstance {\n /**\n * Play the last one\n */\n prev: () => void;\n /**\n * Play the next one\n */\n next: () => void;\n /**\n * Get current item index\n */\n getCurrentIndex: () => number;\n /**\n * Go to index\n */\n goToIndex: (index: number, animated?: boolean) => void;\n}\n\nfunction Carousel<T extends unknown = any>(\n props: ICarouselProps<T>,\n ref: React.Ref<ICarouselInstance>\n) {\n const {\n defaultIndex = 0,\n height = '100%',\n data: _data = [],\n loop = true,\n mode = 'default',\n autoPlay,\n autoPlayReverse,\n autoPlayInterval = 1000,\n parallaxScrollingOffset,\n parallaxScrollingScale,\n style,\n panGestureHandlerProps = {},\n renderItem,\n onSnapToItem,\n onProgressChange,\n windowSize,\n } = props;\n\n usePropsErrorBoundary({\n ...props,\n defaultIndex,\n height,\n data: _data,\n loop,\n mode,\n autoPlay,\n autoPlayReverse,\n autoPlayInterval,\n parallaxScrollingOffset,\n parallaxScrollingScale,\n style,\n panGestureHandlerProps,\n // @ts-ignore\n renderItem,\n onSnapToItem,\n onProgressChange,\n });\n\n const timingConfig = {\n ...defaultSpringConfig,\n ...props.springConfig,\n };\n const width = Math.round(props.width);\n const defaultHandlerOffsetX = -Math.abs(defaultIndex * width);\n const handlerOffsetX = useSharedValue<number>(defaultHandlerOffsetX);\n const data = React.useMemo<T[]>(() => {\n if (!loop) return _data;\n\n if (_data.length === 1) {\n return [_data[0], _data[0], _data[0]];\n }\n\n if (_data.length === 2) {\n return [_data[0], _data[1], _data[0], _data[1]];\n }\n\n return _data;\n }, [_data, loop]);\n\n const indexController = useIndexController({\n originalLength: _data.length,\n length: data.length,\n handlerOffsetX,\n width,\n loop,\n onChange: (i) => onSnapToItem && runOnJS(onSnapToItem)(i),\n });\n\n const carouselController = useCarouselController({\n loop,\n width,\n handlerOffsetX,\n indexController,\n disable: !data.length,\n onScrollBegin: () => runOnJS(onScrollBegin)(),\n onScrollEnd: () => runOnJS(onScrollEnd)(),\n });\n\n const { run, pause } = useAutoPlay({\n autoPlay,\n autoPlayInterval,\n autoPlayReverse,\n carouselController,\n });\n\n const { index, sharedPreIndex, sharedIndex, computedIndex } =\n indexController;\n\n const onScrollBegin = React.useCallback(() => {\n pause();\n props.onScrollBegin?.();\n }, [pause, props]);\n\n const onScrollEnd = React.useCallback(() => {\n run();\n computedIndex();\n props.onScrollEnd?.(sharedPreIndex.current, sharedIndex.current);\n }, [sharedPreIndex, sharedIndex, computedIndex, props, run]);\n\n const offsetX = useDerivedValue(() => {\n const totalWidth = width * data.length;\n const x = handlerOffsetX.value % totalWidth;\n\n if (!loop) {\n return handlerOffsetX.value;\n }\n return isNaN(x) ? 0 : x;\n }, [loop, width, data]);\n\n useAnimatedReaction(\n () => offsetX.value,\n (value) => {\n let absoluteProgress = Math.abs(value / width);\n if (value > 0) {\n absoluteProgress = data.length - absoluteProgress;\n }\n !!onProgressChange &&\n runOnJS(onProgressChange)(value, absoluteProgress);\n },\n [onProgressChange, data]\n );\n\n const next = React.useCallback(() => {\n return carouselController.next();\n }, [carouselController]);\n\n const prev = React.useCallback(() => {\n return carouselController.prev();\n }, [carouselController]);\n\n const getCurrentIndex = React.useCallback(() => {\n return index.value;\n }, [index]);\n\n const goToIndex = React.useCallback(\n (i: number, animated?: boolean) => {\n carouselController.to(i, animated);\n },\n [carouselController]\n );\n\n const animatedListScrollHandler =\n useAnimatedGestureHandler<PanGestureHandlerGestureEvent>(\n {\n onStart: (_, ctx: any) => {\n runOnJS(pause)();\n runOnJS(onScrollBegin)();\n cancelAnimation(handlerOffsetX);\n ctx.currentContentOffsetX = handlerOffsetX.value;\n ctx.start = true;\n },\n onActive: (e, ctx: any) => {\n const { translationX } = e;\n if (\n !loop &&\n (handlerOffsetX.value >= 0 ||\n handlerOffsetX.value <= -(data.length - 1) * width)\n ) {\n handlerOffsetX.value =\n ctx.currentContentOffsetX + translationX / 2;\n return;\n }\n handlerOffsetX.value =\n ctx.currentContentOffsetX + translationX;\n },\n onEnd: (e) => {\n function _withAnimationCallback(num: number) {\n return withSpring(\n num,\n Object.assign({}, timingConfig, {\n velocity: e.velocityX,\n }),\n (isFinished) => {\n if (isFinished) {\n runOnJS(onScrollEnd)();\n }\n }\n );\n }\n\n const page = Math.round(handlerOffsetX.value / width);\n\n const velocityPage = Math.round(\n (handlerOffsetX.value + e.velocityX) / width\n );\n\n let pageWithVelocity = Math.min(\n page + 1,\n Math.max(page - 1, velocityPage)\n );\n\n if (!loop) {\n pageWithVelocity = Math.max(\n -(data.length - 1),\n Math.min(0, pageWithVelocity)\n );\n }\n\n if (loop) {\n handlerOffsetX.value = _withAnimationCallback(\n pageWithVelocity * width\n );\n return;\n }\n if (handlerOffsetX.value >= 0) {\n handlerOffsetX.value = _withAnimationCallback(0);\n return;\n }\n\n if (handlerOffsetX.value <= -(data.length - 1) * width) {\n handlerOffsetX.value = _withAnimationCallback(\n -(data.length - 1) * width\n );\n return;\n }\n\n handlerOffsetX.value = _withAnimationCallback(\n pageWithVelocity * width\n );\n },\n },\n [loop, data, onScrollBegin, onScrollEnd]\n );\n\n React.useImperativeHandle(\n ref,\n () => ({\n next,\n prev,\n getCurrentIndex,\n goToIndex,\n }),\n [getCurrentIndex, goToIndex, next, prev]\n );\n\n const visibleRanges = useVisibleRanges({\n total: data.length,\n viewSize: width,\n translation: handlerOffsetX,\n windowSize,\n });\n\n const renderLayout = React.useCallback(\n (item: T, i: number) => {\n switch (mode) {\n case 'parallax':\n return (\n <ParallaxLayout\n parallaxScrollingOffset={parallaxScrollingOffset}\n parallaxScrollingScale={parallaxScrollingScale}\n data={data}\n width={width}\n handlerOffsetX={offsetX}\n index={i}\n key={i}\n loop={loop}\n visibleRanges={visibleRanges}\n >\n {renderItem(item, i)}\n </ParallaxLayout>\n );\n default:\n return (\n <CarouselItem\n data={data}\n width={width}\n height={height}\n handlerOffsetX={offsetX}\n index={i}\n key={i}\n loop={loop}\n visibleRanges={visibleRanges}\n >\n {renderItem(item, i)}\n </CarouselItem>\n );\n }\n },\n [\n loop,\n mode,\n data,\n height,\n offsetX,\n parallaxScrollingOffset,\n parallaxScrollingScale,\n width,\n renderItem,\n visibleRanges,\n ]\n );\n\n return (\n <PanGestureHandler\n {...panGestureHandlerProps}\n onGestureEvent={animatedListScrollHandler}\n >\n <Animated.View\n // eslint-disable-next-line react-native/no-inline-styles\n style={{\n ...style,\n width,\n height,\n flexDirection: 'row',\n position: 'relative',\n }}\n >\n {data.map(renderLayout)}\n </Animated.View>\n </PanGestureHandler>\n );\n}\n\nexport default React.forwardRef(Carousel) as typeof Carousel;\n"]}
|
|
@@ -27,7 +27,8 @@ const CarouselItem = props => {
|
|
|
27
27
|
width,
|
|
28
28
|
height = '100%',
|
|
29
29
|
loop,
|
|
30
|
-
data
|
|
30
|
+
data,
|
|
31
|
+
visibleRanges
|
|
31
32
|
} = props;
|
|
32
33
|
const x = (0, _useOffsetX.useOffsetX)({
|
|
33
34
|
handlerOffsetX,
|
|
@@ -35,7 +36,7 @@ const CarouselItem = props => {
|
|
|
35
36
|
width,
|
|
36
37
|
data,
|
|
37
38
|
loop
|
|
38
|
-
});
|
|
39
|
+
}, visibleRanges);
|
|
39
40
|
const offsetXStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
|
|
40
41
|
return {
|
|
41
42
|
transform: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["CarouselItem.tsx"],"names":["CarouselItem","props","handlerOffsetX","index","children","width","height","loop","data","x","offsetXStyle","transform","translateX","value"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["CarouselItem.tsx"],"names":["CarouselItem","props","handlerOffsetX","index","children","width","height","loop","data","visibleRanges","x","offsetXStyle","transform","translateX","value"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;;;;;;;AAGO,MAAMA,YAQX,GAAIC,KAAD,IAAW;AACZ,QAAM;AACFC,IAAAA,cADE;AAEFC,IAAAA,KAFE;AAGFC,IAAAA,QAHE;AAIFC,IAAAA,KAJE;AAKFC,IAAAA,MAAM,GAAG,MALP;AAMFC,IAAAA,IANE;AAOFC,IAAAA,IAPE;AAQFC,IAAAA;AARE,MASFR,KATJ;AAWA,QAAMS,CAAC,GAAG,4BACN;AACIR,IAAAA,cADJ;AAEIC,IAAAA,KAFJ;AAGIE,IAAAA,KAHJ;AAIIG,IAAAA,IAJJ;AAKID,IAAAA;AALJ,GADM,EAQNE,aARM,CAAV;AAWA,QAAME,YAAY,GAAG,6CAAiB,MAAM;AACxC,WAAO;AACHC,MAAAA,SAAS,EAAE,CAAC;AAAEC,QAAAA,UAAU,EAAEH,CAAC,CAACI,KAAF,GAAUX,KAAK,GAAGE;AAAhC,OAAD;AADR,KAAP;AAGH,GAJoB,EAIlB,EAJkB,CAArB;AAMA,sBACI,6BAAC,8BAAD,CAAU,IAAV;AAAe,IAAA,KAAK,EAAEM;AAAtB,kBACI,6BAAC,iBAAD;AAAM,IAAA,KAAK,EAAE;AAAEN,MAAAA,KAAF;AAASC,MAAAA;AAAT;AAAb,KAAiCF,QAAjC,CADJ,CADJ;AAKH,CA1CM","sourcesContent":["import React from 'react';\nimport { FlexStyle, View } from 'react-native';\nimport Animated, { useAnimatedStyle } from 'react-native-reanimated';\nimport { useOffsetX } from './hooks/useOffsetX';\nimport type { IVisibleRanges } from './hooks/useVisibleRanges';\n\nexport const CarouselItem: React.FC<{\n loop?: boolean;\n index: number;\n handlerOffsetX: Animated.SharedValue<number>;\n width: number;\n data: unknown[];\n height?: FlexStyle['height'];\n visibleRanges: IVisibleRanges;\n}> = (props) => {\n const {\n handlerOffsetX,\n index,\n children,\n width,\n height = '100%',\n loop,\n data,\n visibleRanges,\n } = props;\n\n const x = useOffsetX(\n {\n handlerOffsetX,\n index,\n width,\n data,\n loop,\n },\n visibleRanges\n );\n\n const offsetXStyle = useAnimatedStyle(() => {\n return {\n transform: [{ translateX: x.value - index * width }],\n };\n }, []);\n\n return (\n <Animated.View style={offsetXStyle}>\n <View style={{ width, height }}>{children}</View>\n </Animated.View>\n );\n};\n"]}
|
|
@@ -7,7 +7,7 @@ exports.useOffsetX = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _reactNativeReanimated = require("react-native-reanimated");
|
|
9
9
|
|
|
10
|
-
const useOffsetX = opts => {
|
|
10
|
+
const useOffsetX = (opts, visibleRanges) => {
|
|
11
11
|
const {
|
|
12
12
|
handlerOffsetX,
|
|
13
13
|
index,
|
|
@@ -22,6 +22,15 @@ const useOffsetX = opts => {
|
|
|
22
22
|
const TOTAL_WIDTH = width * ITEM_LENGTH;
|
|
23
23
|
const HALF_WIDTH = 0.5 * width;
|
|
24
24
|
const x = (0, _reactNativeReanimated.useDerivedValue)(() => {
|
|
25
|
+
const {
|
|
26
|
+
negativeRange,
|
|
27
|
+
positiveRange
|
|
28
|
+
} = visibleRanges.value;
|
|
29
|
+
|
|
30
|
+
if ((index < negativeRange[0] || index > negativeRange[1]) && (index < positiveRange[0] || index > positiveRange[1])) {
|
|
31
|
+
return Number.MAX_SAFE_INTEGER;
|
|
32
|
+
}
|
|
33
|
+
|
|
25
34
|
if (loop) {
|
|
26
35
|
const positiveCount = type === 'positive' ? viewCount : VALID_LENGTH - viewCount;
|
|
27
36
|
let startPos = width * index;
|
|
@@ -38,7 +47,7 @@ const useOffsetX = opts => {
|
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
return handlerOffsetX.value + width * index;
|
|
41
|
-
}, [loop, data, viewCount, type]);
|
|
50
|
+
}, [loop, data, viewCount, type, visibleRanges]);
|
|
42
51
|
return x;
|
|
43
52
|
};
|
|
44
53
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useOffsetX.ts"],"names":["useOffsetX","opts","handlerOffsetX","index","width","loop","data","type","viewCount","Math","round","length","ITEM_LENGTH","VALID_LENGTH","TOTAL_WIDTH","HALF_WIDTH","x","positiveCount","startPos","MAX","MIN","inputRange","outputRange","
|
|
1
|
+
{"version":3,"sources":["useOffsetX.ts"],"names":["useOffsetX","opts","visibleRanges","handlerOffsetX","index","width","loop","data","type","viewCount","Math","round","length","ITEM_LENGTH","VALID_LENGTH","TOTAL_WIDTH","HALF_WIDTH","x","negativeRange","positiveRange","value","Number","MAX_SAFE_INTEGER","positiveCount","startPos","MAX","MIN","inputRange","outputRange","map","Extrapolate","CLAMP"],"mappings":";;;;;;;AAAA;;AAiBO,MAAMA,UAAU,GAAG,CAACC,IAAD,EAAcC,aAAd,KAAgD;AACtE,QAAM;AACFC,IAAAA,cADE;AAEFC,IAAAA,KAFE;AAGFC,IAAAA,KAHE;AAIFC,IAAAA,IAJE;AAKFC,IAAAA,IALE;AAMFC,IAAAA,IAAI,GAAG,UANL;AAOFC,IAAAA,SAAS,GAAGC,IAAI,CAACC,KAAL,CAAW,CAACJ,IAAI,CAACK,MAAL,GAAc,CAAf,IAAoB,CAA/B;AAPV,MAQFX,IARJ;AASA,QAAMY,WAAW,GAAGN,IAAI,CAACK,MAAzB;AACA,QAAME,YAAY,GAAGD,WAAW,GAAG,CAAnC;AACA,QAAME,WAAW,GAAGV,KAAK,GAAGQ,WAA5B;AACA,QAAMG,UAAU,GAAG,MAAMX,KAAzB;AAEA,QAAMY,CAAC,GAAG,4CAAgB,MAAM;AAC5B,UAAM;AAAEC,MAAAA,aAAF;AAAiBC,MAAAA;AAAjB,QAAmCjB,aAAa,CAACkB,KAAvD;;AACA,QACI,CAAChB,KAAK,GAAGc,aAAa,CAAC,CAAD,CAArB,IAA4Bd,KAAK,GAAGc,aAAa,CAAC,CAAD,CAAlD,MACCd,KAAK,GAAGe,aAAa,CAAC,CAAD,CAArB,IAA4Bf,KAAK,GAAGe,aAAa,CAAC,CAAD,CADlD,CADJ,EAGE;AACE,aAAOE,MAAM,CAACC,gBAAd;AACH;;AACD,QAAIhB,IAAJ,EAAU;AACN,YAAMiB,aAAa,GACff,IAAI,KAAK,UAAT,GAAsBC,SAAtB,GAAkCK,YAAY,GAAGL,SADrD;AAGA,UAAIe,QAAQ,GAAGnB,KAAK,GAAGD,KAAvB;;AACA,UAAIA,KAAK,GAAGmB,aAAZ,EAA2B;AACvBC,QAAAA,QAAQ,GAAG,CAACpB,KAAK,GAAGS,WAAT,IAAwBR,KAAnC;AACH;;AAED,YAAMoB,GAAG,GAAGF,aAAa,GAAGlB,KAA5B;AACA,YAAMqB,GAAG,GAAG,EAAE,CAACZ,YAAY,GAAGS,aAAhB,IAAiClB,KAAnC,CAAZ;AAEA,YAAMsB,UAAU,GAAG,CACf,CAACZ,WADc,EAEfW,GAAG,GAAGV,UAAN,GAAmBQ,QAAnB,GAA8B,CAFf,EAGfE,GAAG,GAAGV,UAAN,GAAmBQ,QAHJ,EAIf,CAJe,EAKfC,GAAG,GAAGT,UAAN,GAAmBQ,QALJ,EAMfC,GAAG,GAAGT,UAAN,GAAmBQ,QAAnB,GAA8B,CANf,EAOfT,WAPe,CAAnB;AAUA,YAAMa,WAAW,GAAG,CAChBJ,QADgB,EAEhBC,GAAG,GAAGT,UAAN,GAAmB,CAFH,EAGhBU,GAAG,GAAGV,UAHU,EAIhBQ,QAJgB,EAKhBC,GAAG,GAAGT,UALU,EAMhBU,GAAG,GAAGV,UAAN,GAAmB,CANH,EAOhBQ,QAPgB,CAApB;AAUA,aAAO,wCACHd,IAAI,CAACC,KAAL,CAAWR,cAAc,CAACiB,KAA1B,CADG,EAEHO,UAAU,CAACE,GAAX,CAAenB,IAAI,CAACC,KAApB,CAFG,EAGHiB,WAAW,CAACC,GAAZ,CAAgBnB,IAAI,CAACC,KAArB,CAHG,EAIHmB,mCAAYC,KAJT,CAAP;AAMH;;AAED,WAAO5B,cAAc,CAACiB,KAAf,GAAuBf,KAAK,GAAGD,KAAtC;AACH,GAjDS,EAiDP,CAACE,IAAD,EAAOC,IAAP,EAAaE,SAAb,EAAwBD,IAAxB,EAA8BN,aAA9B,CAjDO,CAAV;AAmDA,SAAOe,CAAP;AACH,CAnEM","sourcesContent":["import Animated, {\n Extrapolate,\n interpolate,\n useDerivedValue,\n} from 'react-native-reanimated';\nimport type { IVisibleRanges } from './useVisibleRanges';\n\ninterface IOpts {\n index: number;\n width: number;\n handlerOffsetX: Animated.SharedValue<number>;\n data: unknown[];\n type?: 'positive' | 'negative';\n viewCount?: number;\n loop?: boolean;\n}\n\nexport const useOffsetX = (opts: IOpts, visibleRanges: IVisibleRanges) => {\n const {\n handlerOffsetX,\n index,\n width,\n loop,\n data,\n type = 'positive',\n viewCount = Math.round((data.length - 1) / 2),\n } = opts;\n const ITEM_LENGTH = data.length;\n const VALID_LENGTH = ITEM_LENGTH - 1;\n const TOTAL_WIDTH = width * ITEM_LENGTH;\n const HALF_WIDTH = 0.5 * width;\n\n const x = useDerivedValue(() => {\n const { negativeRange, positiveRange } = visibleRanges.value;\n if (\n (index < negativeRange[0] || index > negativeRange[1]) &&\n (index < positiveRange[0] || index > positiveRange[1])\n ) {\n return Number.MAX_SAFE_INTEGER;\n }\n if (loop) {\n const positiveCount =\n type === 'positive' ? viewCount : VALID_LENGTH - viewCount;\n\n let startPos = width * index;\n if (index > positiveCount) {\n startPos = (index - ITEM_LENGTH) * width;\n }\n\n const MAX = positiveCount * width;\n const MIN = -((VALID_LENGTH - positiveCount) * width);\n\n const inputRange = [\n -TOTAL_WIDTH,\n MIN - HALF_WIDTH - startPos - 1,\n MIN - HALF_WIDTH - startPos,\n 0,\n MAX + HALF_WIDTH - startPos,\n MAX + HALF_WIDTH - startPos + 1,\n TOTAL_WIDTH,\n ];\n\n const outputRange = [\n startPos,\n MAX + HALF_WIDTH - 1,\n MIN - HALF_WIDTH,\n startPos,\n MAX + HALF_WIDTH,\n MIN - HALF_WIDTH + 1,\n startPos,\n ];\n\n return interpolate(\n Math.round(handlerOffsetX.value),\n inputRange.map(Math.round),\n outputRange.map(Math.round),\n Extrapolate.CLAMP\n );\n }\n\n return handlerOffsetX.value + width * index;\n }, [loop, data, viewCount, type, visibleRanges]);\n\n return x;\n};\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useVisibleRanges = useVisibleRanges;
|
|
7
|
+
|
|
8
|
+
var _reactNativeReanimated = require("react-native-reanimated");
|
|
9
|
+
|
|
10
|
+
function useVisibleRanges(options) {
|
|
11
|
+
const {
|
|
12
|
+
total,
|
|
13
|
+
viewSize,
|
|
14
|
+
windowSize = 0,
|
|
15
|
+
translation
|
|
16
|
+
} = options;
|
|
17
|
+
const ranges = (0, _reactNativeReanimated.useDerivedValue)(() => {
|
|
18
|
+
const positiveCount = Math.round(windowSize / 2);
|
|
19
|
+
const negativeCount = windowSize - positiveCount;
|
|
20
|
+
let curIndex = Math.round(-translation.value / viewSize);
|
|
21
|
+
curIndex = curIndex < 0 ? curIndex % total + total : curIndex;
|
|
22
|
+
const negativeRange = [(curIndex - negativeCount + total) % total, (curIndex - 1 + total) % total];
|
|
23
|
+
const positiveRange = [(curIndex + total) % total, (curIndex + positiveCount + total) % total];
|
|
24
|
+
|
|
25
|
+
if (negativeRange[0] < total && negativeRange[0] > negativeRange[1]) {
|
|
26
|
+
negativeRange[1] = total - 1;
|
|
27
|
+
positiveRange[0] = 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (positiveRange[0] > positiveRange[1]) {
|
|
31
|
+
negativeRange[1] = total - 1;
|
|
32
|
+
positiveRange[0] = 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
negativeRange,
|
|
37
|
+
positiveRange
|
|
38
|
+
};
|
|
39
|
+
}, [total, windowSize, translation]);
|
|
40
|
+
return ranges;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=useVisibleRanges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["useVisibleRanges.tsx"],"names":["useVisibleRanges","options","total","viewSize","windowSize","translation","ranges","positiveCount","Math","round","negativeCount","curIndex","value","negativeRange","positiveRange"],"mappings":";;;;;;;AACA;;AAOO,SAASA,gBAAT,CAA0BC,OAA1B,EAKY;AACf,QAAM;AAAEC,IAAAA,KAAF;AAASC,IAAAA,QAAT;AAAmBC,IAAAA,UAAU,GAAG,CAAhC;AAAmCC,IAAAA;AAAnC,MAAmDJ,OAAzD;AAEA,QAAMK,MAAM,GAAG,4CAAgB,MAAM;AACjC,UAAMC,aAAa,GAAGC,IAAI,CAACC,KAAL,CAAWL,UAAU,GAAG,CAAxB,CAAtB;AACA,UAAMM,aAAa,GAAGN,UAAU,GAAGG,aAAnC;AACA,QAAII,QAAQ,GAAGH,IAAI,CAACC,KAAL,CAAW,CAACJ,WAAW,CAACO,KAAb,GAAqBT,QAAhC,CAAf;AACAQ,IAAAA,QAAQ,GAAGA,QAAQ,GAAG,CAAX,GAAgBA,QAAQ,GAAGT,KAAZ,GAAqBA,KAApC,GAA4CS,QAAvD;AACA,UAAME,aAAa,GAAG,CAClB,CAACF,QAAQ,GAAGD,aAAX,GAA2BR,KAA5B,IAAqCA,KADnB,EAElB,CAACS,QAAQ,GAAG,CAAX,GAAeT,KAAhB,IAAyBA,KAFP,CAAtB;AAIA,UAAMY,aAAa,GAAG,CAClB,CAACH,QAAQ,GAAGT,KAAZ,IAAqBA,KADH,EAElB,CAACS,QAAQ,GAAGJ,aAAX,GAA2BL,KAA5B,IAAqCA,KAFnB,CAAtB;;AAIA,QAAIW,aAAa,CAAC,CAAD,CAAb,GAAmBX,KAAnB,IAA4BW,aAAa,CAAC,CAAD,CAAb,GAAmBA,aAAa,CAAC,CAAD,CAAhE,EAAqE;AACjEA,MAAAA,aAAa,CAAC,CAAD,CAAb,GAAmBX,KAAK,GAAG,CAA3B;AACAY,MAAAA,aAAa,CAAC,CAAD,CAAb,GAAmB,CAAnB;AACH;;AACD,QAAIA,aAAa,CAAC,CAAD,CAAb,GAAmBA,aAAa,CAAC,CAAD,CAApC,EAAyC;AACrCD,MAAAA,aAAa,CAAC,CAAD,CAAb,GAAmBX,KAAK,GAAG,CAA3B;AACAY,MAAAA,aAAa,CAAC,CAAD,CAAb,GAAmB,CAAnB;AACH;;AACD,WAAO;AAAED,MAAAA,aAAF;AAAiBC,MAAAA;AAAjB,KAAP;AACH,GAtBc,EAsBZ,CAACZ,KAAD,EAAQE,UAAR,EAAoBC,WAApB,CAtBY,CAAf;AAwBA,SAAOC,MAAP;AACH","sourcesContent":["import type Animated from 'react-native-reanimated';\nimport { useDerivedValue } from 'react-native-reanimated';\n\nexport type IVisibleRanges = Animated.SharedValue<{\n negativeRange: number[];\n positiveRange: number[];\n}>;\n\nexport function useVisibleRanges(options: {\n total: number;\n viewSize: number;\n windowSize?: number;\n translation: Animated.SharedValue<number>;\n}): IVisibleRanges {\n const { total, viewSize, windowSize = 0, translation } = options;\n\n const ranges = useDerivedValue(() => {\n const positiveCount = Math.round(windowSize / 2);\n const negativeCount = windowSize - positiveCount;\n let curIndex = Math.round(-translation.value / viewSize);\n curIndex = curIndex < 0 ? (curIndex % total) + total : curIndex;\n const negativeRange = [\n (curIndex - negativeCount + total) % total,\n (curIndex - 1 + total) % total,\n ];\n const positiveRange = [\n (curIndex + total) % total,\n (curIndex + positiveCount + total) % total,\n ];\n if (negativeRange[0] < total && negativeRange[0] > negativeRange[1]) {\n negativeRange[1] = total - 1;\n positiveRange[0] = 0;\n }\n if (positiveRange[0] > positiveRange[1]) {\n negativeRange[1] = total - 1;\n positiveRange[0] = 0;\n }\n return { negativeRange, positiveRange };\n }, [total, windowSize, translation]);\n\n return ranges;\n}\n"]}
|
|
@@ -29,7 +29,8 @@ const ParallaxLayout = props => {
|
|
|
29
29
|
width,
|
|
30
30
|
loop,
|
|
31
31
|
data,
|
|
32
|
-
children
|
|
32
|
+
children,
|
|
33
|
+
visibleRanges
|
|
33
34
|
} = props;
|
|
34
35
|
const x = (0, _useOffsetX.useOffsetX)({
|
|
35
36
|
handlerOffsetX,
|
|
@@ -37,7 +38,7 @@ const ParallaxLayout = props => {
|
|
|
37
38
|
width,
|
|
38
39
|
data,
|
|
39
40
|
loop
|
|
40
|
-
});
|
|
41
|
+
}, visibleRanges);
|
|
41
42
|
const offsetXStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
|
|
42
43
|
const baseTranslateX = x.value - index * width;
|
|
43
44
|
const padding = (1 - parallaxScrollingScale) * width;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["ParallaxLayout.tsx"],"names":["ParallaxLayout","props","handlerOffsetX","parallaxScrollingOffset","parallaxScrollingScale","index","width","loop","data","children","x","offsetXStyle","baseTranslateX","value","padding","extraOffset","zIndex","Extrapolate","CLAMP","scale","relatedTranslateX","transform","translateX","height","alignSelf","flex"],"mappings":";;;;;;;AACA;;AACA;;AACA;;AAKA;;;;;;;;AARA;
|
|
1
|
+
{"version":3,"sources":["ParallaxLayout.tsx"],"names":["ParallaxLayout","props","handlerOffsetX","parallaxScrollingOffset","parallaxScrollingScale","index","width","loop","data","children","visibleRanges","x","offsetXStyle","baseTranslateX","value","padding","extraOffset","zIndex","Extrapolate","CLAMP","scale","relatedTranslateX","transform","translateX","height","alignSelf","flex"],"mappings":";;;;;;;AACA;;AACA;;AACA;;AAKA;;;;;;;;AARA;AAWO,MAAMA,cASX,GAAIC,KAAD,IAAW;AACZ,QAAM;AACFC,IAAAA,cADE;AAEFC,IAAAA,uBAAuB,GAAG,GAFxB;AAGFC,IAAAA,sBAAsB,GAAG,GAHvB;AAIFC,IAAAA,KAJE;AAKFC,IAAAA,KALE;AAMFC,IAAAA,IANE;AAOFC,IAAAA,IAPE;AAQFC,IAAAA,QARE;AASFC,IAAAA;AATE,MAUFT,KAVJ;AAYA,QAAMU,CAAC,GAAG,4BACN;AACIT,IAAAA,cADJ;AAEIG,IAAAA,KAFJ;AAGIC,IAAAA,KAHJ;AAIIE,IAAAA,IAJJ;AAKID,IAAAA;AALJ,GADM,EAQNG,aARM,CAAV;AAWA,QAAME,YAAY,GAAG,6CAAiB,MAAM;AACxC,UAAMC,cAAc,GAAGF,CAAC,CAACG,KAAF,GAAUT,KAAK,GAAGC,KAAzC;AACA,UAAMS,OAAO,GAAG,CAAC,IAAIX,sBAAL,IAA+BE,KAA/C;AACA,UAAMU,WAAW,GAAGX,KAAK,GAAGU,OAAR,GAAkBA,OAAO,GAAG,CAAhD;AAEA,UAAME,MAAM,GAAG,wCACXN,CAAC,CAACG,KADS,EAEX,CAAC,CAACR,KAAF,EAAS,CAAT,EAAYA,KAAZ,CAFW,EAGX,CAAC,CAAD,EAAIA,KAAJ,EAAW,CAAX,CAHW,EAIXY,mCAAYC,KAJD,CAAf;AAMA,UAAMC,KAAK,GAAG,wCACVT,CAAC,CAACG,KADQ,EAEV,CAAC,CAACR,KAAF,EAAS,CAAT,EAAYA,KAAZ,CAFU,EAGV,CAACF,sBAAD,EAAyB,CAAzB,EAA4BA,sBAA5B,CAHU,EAIVc,mCAAYC,KAJF,CAAd;AAMA,UAAME,iBAAiB,GAAG,wCACtBV,CAAC,CAACG,KADoB,EAEtB,CAAC,CAACR,KAAF,EAAS,CAAT,EAAYA,KAAZ,CAFsB,EAGtB,CAACH,uBAAD,EAA0B,CAA1B,EAA6B,CAACA,uBAA9B,CAHsB,EAItBe,mCAAYC,KAJU,CAA1B;AAMA,WAAO;AACHG,MAAAA,SAAS,EAAE,CACP;AACIC,QAAAA,UAAU,EACNV,cAAc,GAAGG,WAAjB,GAA+BK;AAFvC,OADO,EAKP;AAAED,QAAAA;AAAF,OALO,CADR;AAQHH,MAAAA;AARG,KAAP;AAUH,GAjCoB,EAiClB,CAACV,IAAD,CAjCkB,CAArB;AAmCA,sBACI,6BAAC,8BAAD,CAAU,IAAV;AACI,IAAA,KAAK,EAAE,CACH;AACID,MAAAA,KAAK,EAAG,GAAEF,sBAAsB,GAAG,GAAI,GAD3C;AAEIoB,MAAAA,MAAM,EAAG,GAAEpB,sBAAsB,GAAG,GAAI,GAF5C;AAGIqB,MAAAA,SAAS,EAAE;AAHf,KADG,EAMHb,YANG;AADX,kBAUI,6BAAC,iBAAD;AAAM,IAAA,KAAK,EAAE;AAAEc,MAAAA,IAAI,EAAE;AAAR;AAAb,KAA2BjB,QAA3B,CAVJ,CADJ;AAcH,CAlFM","sourcesContent":["/* eslint-disable react-native/no-inline-styles */\nimport React from 'react';\nimport { View } from 'react-native';\nimport Animated, {\n Extrapolate,\n interpolate,\n useAnimatedStyle,\n} from 'react-native-reanimated';\nimport { useOffsetX } from '../hooks/useOffsetX';\nimport type { IVisibleRanges } from '../hooks/useVisibleRanges';\n\nexport const ParallaxLayout: React.FC<{\n loop?: boolean;\n parallaxScrollingOffset?: number;\n parallaxScrollingScale?: number;\n handlerOffsetX: Animated.SharedValue<number>;\n index: number;\n width: number;\n data: unknown[];\n visibleRanges: IVisibleRanges;\n}> = (props) => {\n const {\n handlerOffsetX,\n parallaxScrollingOffset = 100,\n parallaxScrollingScale = 0.8,\n index,\n width,\n loop,\n data,\n children,\n visibleRanges,\n } = props;\n\n const x = useOffsetX(\n {\n handlerOffsetX,\n index,\n width,\n data,\n loop,\n },\n visibleRanges\n );\n\n const offsetXStyle = useAnimatedStyle(() => {\n const baseTranslateX = x.value - index * width;\n const padding = (1 - parallaxScrollingScale) * width;\n const extraOffset = index * padding + padding / 2;\n\n const zIndex = interpolate(\n x.value,\n [-width, 0, width],\n [0, width, 0],\n Extrapolate.CLAMP\n );\n const scale = interpolate(\n x.value,\n [-width, 0, width],\n [parallaxScrollingScale, 1, parallaxScrollingScale],\n Extrapolate.CLAMP\n );\n const relatedTranslateX = interpolate(\n x.value,\n [-width, 0, width],\n [parallaxScrollingOffset, 0, -parallaxScrollingOffset],\n Extrapolate.CLAMP\n );\n return {\n transform: [\n {\n translateX:\n baseTranslateX + extraOffset + relatedTranslateX,\n },\n { scale },\n ],\n zIndex,\n };\n }, [loop]);\n\n return (\n <Animated.View\n style={[\n {\n width: `${parallaxScrollingScale * 100}%`,\n height: `${parallaxScrollingScale * 100}%`,\n alignSelf: 'center',\n },\n offsetXStyle,\n ]}\n >\n <View style={{ flex: 1 }}>{children}</View>\n </Animated.View>\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["log.ts"],"names":["log","msg","console"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACO,SAASA,GAAT,
|
|
1
|
+
{"version":3,"sources":["log.ts"],"names":["log","msg","console"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACO,SAASA,GAAT,CAAa,GAAGC,GAAhB,EAA0B;AAC7BC,EAAAA,OAAO,CAACF,GAAR,CAAY,GAAGC,GAAf;AACH","sourcesContent":["/**\n * In worklet\n * e.g. runOnJS(lop)(...);\n */\nexport function log(...msg: any) {\n console.log(...msg);\n}\n"]}
|
package/lib/module/Carousel.js
CHANGED
|
@@ -9,6 +9,7 @@ import { useCarouselController } from './hooks/useCarouselController';
|
|
|
9
9
|
import { useAutoPlay } from './hooks/useAutoPlay';
|
|
10
10
|
import { useIndexController } from './hooks/useIndexController';
|
|
11
11
|
import { usePropsErrorBoundary } from './hooks/usePropsErrorBoundary';
|
|
12
|
+
import { useVisibleRanges } from './hooks/useVisibleRanges';
|
|
12
13
|
const defaultSpringConfig = {
|
|
13
14
|
damping: 100
|
|
14
15
|
};
|
|
@@ -29,7 +30,8 @@ function Carousel(props, ref) {
|
|
|
29
30
|
panGestureHandlerProps = {},
|
|
30
31
|
renderItem,
|
|
31
32
|
onSnapToItem,
|
|
32
|
-
onProgressChange
|
|
33
|
+
onProgressChange,
|
|
34
|
+
windowSize
|
|
33
35
|
} = props;
|
|
34
36
|
usePropsErrorBoundary({ ...props,
|
|
35
37
|
defaultIndex,
|
|
@@ -207,6 +209,12 @@ function Carousel(props, ref) {
|
|
|
207
209
|
getCurrentIndex,
|
|
208
210
|
goToIndex
|
|
209
211
|
}), [getCurrentIndex, goToIndex, next, prev]);
|
|
212
|
+
const visibleRanges = useVisibleRanges({
|
|
213
|
+
total: data.length,
|
|
214
|
+
viewSize: width,
|
|
215
|
+
translation: handlerOffsetX,
|
|
216
|
+
windowSize
|
|
217
|
+
});
|
|
210
218
|
const renderLayout = React.useCallback((item, i) => {
|
|
211
219
|
switch (mode) {
|
|
212
220
|
case 'parallax':
|
|
@@ -218,7 +226,8 @@ function Carousel(props, ref) {
|
|
|
218
226
|
handlerOffsetX: offsetX,
|
|
219
227
|
index: i,
|
|
220
228
|
key: i,
|
|
221
|
-
loop: loop
|
|
229
|
+
loop: loop,
|
|
230
|
+
visibleRanges: visibleRanges
|
|
222
231
|
}, renderItem(item, i));
|
|
223
232
|
|
|
224
233
|
default:
|
|
@@ -229,10 +238,11 @@ function Carousel(props, ref) {
|
|
|
229
238
|
handlerOffsetX: offsetX,
|
|
230
239
|
index: i,
|
|
231
240
|
key: i,
|
|
232
|
-
loop: loop
|
|
241
|
+
loop: loop,
|
|
242
|
+
visibleRanges: visibleRanges
|
|
233
243
|
}, renderItem(item, i));
|
|
234
244
|
}
|
|
235
|
-
}, [loop, mode, data, height, offsetX, parallaxScrollingOffset, parallaxScrollingScale, width, renderItem]);
|
|
245
|
+
}, [loop, mode, data, height, offsetX, parallaxScrollingOffset, parallaxScrollingScale, width, renderItem, visibleRanges]);
|
|
236
246
|
return /*#__PURE__*/React.createElement(PanGestureHandler, _extends({}, panGestureHandlerProps, {
|
|
237
247
|
onGestureEvent: animatedListScrollHandler
|
|
238
248
|
}), /*#__PURE__*/React.createElement(Animated.View, {
|