diff --git a/README.md b/README.md
index ce89881a..fcc8aa63 100644
--- a/README.md
+++ b/README.md
@@ -17,13 +17,14 @@ English | [简体中文](./README.zh-CN.md)
## Here comes the official edition!
+
`v1` has been born, now the carousel will be more natural, and fixed various bugs in the 0.x version, this library will continue to maintain, rest assured to use! [come and experience](https://snack.expo.dev/@zhaodonghao586/simple-carousel) 🎉🎉🎉
Updates:
-- Reconstructed some logic, sliding animation more smooth, natural
-- timingConfig -> springConfig (The configuration of the 'duration' property is no longer supported by this configuration)
-- [...](https://github.com/dohooo/react-native-reanimated-carousel/releases/tag/v1.0.0)
+- Reconstructed some logic, sliding animation more smooth, natural
+- timingConfig -> springConfig (The configuration of the 'duration' property is no longer supported by this configuration)
+- [...](https://github.com/dohooo/react-native-reanimated-carousel/releases/tag/v1.0.0)
## Reason
@@ -72,52 +73,50 @@ If use EXPO managed workflow please ensure that the version is greater than 41.B
## Usage
```typescript
-import Carousel from "react-native-reanimated-carousel";
+import Carousel from 'react-native-reanimated-carousel';
// ...
- width={width}
- data={[{ color: "red" }, { color: "purple" }, { color: "yellow" }]}
- renderItem={({ color }) => {
- return (
-
- );
- }}
+ width={width}
+ data={[{ color: 'red' }, { color: 'purple' }, { color: 'yellow' }]}
+ renderItem={({ color }) => {
+ return (
+
+ );
+ }}
/>;
```
## Props
-| name | required | default | types | description |
-| ----------------------- | -------- | --------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------- |
-| data | ✅ | | T[] | Carousel items data set |
-| width | ✅ | | number | Specified carousel container width |
-| renderItem | ✅ | | (data: T, index: number) => React.ReactNode | Render carousel item |
-| autoPlay | ❌ | false | boolean | Auto play |
-| autoPlayReverse | ❌ | false | boolean | Auto play reverse playback |
-| autoPlayInterval | ❌ | 1000 | autoPlayInterval | Auto play playback interval |
-| mode | ❌ | defalut | 'default'\|'parallax' | Carousel Animated transitions |
-| loop | ❌ | true | boolean | Carousel loop playback |
-| parallaxScrollingOffset | ❌ | 100 | number | When use 'parallax' Layout props,this prop can be control prev/next item offset |
-| parallaxScrollingScale | ❌ | 0.8 | number | When use 'parallax' Layout props,this prop can be control prev/next item scale |
-| style | ❌ | {} | ViewStyle | Carousel container style |
-| height | ❌ | '100%' | undefined \| string \| number | Specified carousel container height |
-| springConfig | ❌ | {damping: 100} | Animated.WithSpringConfig | Spring config of translation animated |
-| onSnapToItem | ❌ | | (index: number) => void | Callback fired when navigating to an item |
-| onScrollBegin | ❌ | | () => void | Callback fired when scroll begin |
-| onScrollEnd | ❌ | | (previous: number, current: number) => void | Callback fired when scroll end |
-| panGestureHandlerProps | ❌ | {} | Omit,'onHandlerStateChange'> | PanGestureHandler props |
-| 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 ...) |
-
-
-
+| name | required | default | types | description |
+| ----------------------- | -------- | -------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
+| data | ✅ | | T[] | Carousel items data set |
+| width | ✅ | | number | Specified carousel container width |
+| renderItem | ✅ | | (data: T, index: number) => React.ReactNode | Render carousel item |
+| defaultIndex | ❌ | 0 | number | Default index |
+| autoPlay | ❌ | false | boolean | Auto play |
+| autoPlayReverse | ❌ | false | boolean | Auto play reverse playback |
+| autoPlayInterval | ❌ | 1000 | autoPlayInterval | Auto play playback interval |
+| mode | ❌ | defalut | 'default'\|'parallax' | Carousel Animated transitions |
+| loop | ❌ | true | boolean | Carousel loop playback |
+| parallaxScrollingOffset | ❌ | 100 | number | When use 'parallax' Layout props,this prop can be control prev/next item offset |
+| parallaxScrollingScale | ❌ | 0.8 | number | When use 'parallax' Layout props,this prop can be control prev/next item scale |
+| style | ❌ | {} | ViewStyle | Carousel container style |
+| height | ❌ | '100%' | undefined \| string \| number | Specified carousel container height |
+| springConfig | ❌ | {damping: 100} | Animated.WithSpringConfig | Spring config of translation animated |
+| onSnapToItem | ❌ | | (index: number) => void | Callback fired when navigating to an item |
+| onScrollBegin | ❌ | | () => void | Callback fired when scroll begin |
+| onScrollEnd | ❌ | | (previous: number, current: number) => void | Callback fired when scroll end |
+| panGestureHandlerProps | ❌ | {} | Omit,'onHandlerStateChange'> | PanGestureHandler props |
+| 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 ...) |
## Ref
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 4386c66d..ade6df8b 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -17,12 +17,14 @@
## 正式版来了!
-`v1`已经诞生,现在轮播图的滚动将会更加自然,并且修复了0.x版本中出现的各种bug,此库将会持续维护,放心使用! [快来体验](https://snack.expo.dev/@zhaodonghao586/simple-carousel) 🎉🎉🎉
+
+`v1`已经诞生,现在轮播图的滚动将会更加自然,并且修复了 0.x 版本中出现的各种 bug,此库将会持续维护,放心使用! [快来体验](https://snack.expo.dev/@zhaodonghao586/simple-carousel) 🎉🎉🎉
更新:
-- 重构了部分逻辑,滑动动画更加流畅、自然
-- timingConfig -> springConfig (此配置不再支持对`duration`属性的配置)
-- [...](https://github.com/dohooo/react-native-reanimated-carousel/releases/tag/v1.0.0)
+
+- 重构了部分逻辑,滑动动画更加流畅、自然
+- timingConfig -> springConfig (此配置不再支持对`duration`属性的配置)
+- [...](https://github.com/dohooo/react-native-reanimated-carousel/releases/tag/v1.0.0)
## 原因
@@ -71,49 +73,50 @@ npm install react-native-reanimated-carousel
## 使用
```typescript
-import Carousel from "react-native-reanimated-carousel";
+import Carousel from 'react-native-reanimated-carousel';
// ...
- width={width}
- data={[{ color: "red" }, { color: "purple" }, { color: "yellow" }]}
- renderItem={({ color }) => {
- return (
-
- );
- }}
+ width={width}
+ data={[{ color: 'red' }, { color: 'purple' }, { color: 'yellow' }]}
+ renderItem={({ color }) => {
+ return (
+
+ );
+ }}
/>;
```
## Props
-| name | required | default | types | description |
-| ----------------------- | -------- | --------------- | -------------------------------------------------------------- | ----------------------------------------------------------------------- |
-| data | ✅ | | T[] | 即将渲染的数据集合 |
-| width | ✅ | | number | 轮播图容器的宽度 |
-| renderItem | ✅ | | (data: T, index: number) => React.ReactNode | 渲染元素的方法 |
-| autoPlay | ❌ | false | boolean | 是否自动播放 |
-| autoPlayReverse | ❌ | false | boolean | 是否倒序自动播放 |
-| autoPlayInterval | ❌ | 1000 | autoPlayInterval | 自动播放的间隔 |
-| mode | ❌ | defalut | 'default'\|'parallax' | 轮播图播放模式,`default`为默认无任何 UI 效果,演示图片使用的`parallax` |
-| loop | ❌ | true | boolean | 是否循环播放 |
-| parallaxScrollingOffset | ❌ | 100 | number | 当使用 mode=`parallax`,这个属性可以控制两侧图片离中间元素的距离 |
-| parallaxScrollingScale | ❌ | 0.8 | number | 当使用 mode=`parallax`,这个属性可以控制两侧图片的缩放比例 |
-| style | ❌ | {} | ViewStyle | 轮播图容器样式 |
-| height | ❌ | '100%' | undefined \| string \| number | 指定轮播图容器高度 |
-| springConfig | ❌ | {damping: 100} | Animated.WithSpringConfig | 配置动画效果 |
-| onSnapToItem | ❌ | | (index: number) => void | 切换至另一张轮播图时触发 |
-| onScrollBegin | ❌ | | () => void | 切换动画开始时触发 |
-| onScrollEnd | ❌ | | (previous: number, current: number) => void | 切换动画结束时触发 |
-| panGestureHandlerProps | ❌ | {} | Omit,'onHandlerStateChange'> | PanGestureHandler props |
-| onProgressChange | ❌ | | onProgressChange?: (offsetProgress: number,absoluteProgress: number) => void | 当滚动进度发生变化时触发 `offsetProgress`:总的偏移值 (0 390 780 ...); `absoluteProgress`:转化为index的进度变化 (0 1 2 ...) |
+| name | required | default | types | description |
+| ----------------------- | -------- | -------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
+| data | ✅ | | T[] | 即将渲染的数据集合 |
+| width | ✅ | | number | 轮播图容器的宽度 |
+| renderItem | ✅ | | (data: T, index: number) => React.ReactNode | 渲染元素的方法 |
+| defaultIndex | ❌ | 0 | number | 默认 index |
+| autoPlay | ❌ | false | boolean | 是否自动播放 |
+| autoPlayReverse | ❌ | false | boolean | 是否倒序自动播放 |
+| autoPlayInterval | ❌ | 1000 | autoPlayInterval | 自动播放的间隔 |
+| mode | ❌ | defalut | 'default'\|'parallax' | 轮播图播放模式,`default`为默认无任何 UI 效果,演示图片使用的`parallax` |
+| loop | ❌ | true | boolean | 是否循环播放 |
+| parallaxScrollingOffset | ❌ | 100 | number | 当使用 mode=`parallax`,这个属性可以控制两侧图片离中间元素的距离 |
+| parallaxScrollingScale | ❌ | 0.8 | number | 当使用 mode=`parallax`,这个属性可以控制两侧图片的缩放比例 |
+| style | ❌ | {} | ViewStyle | 轮播图容器样式 |
+| height | ❌ | '100%' | undefined \| string \| number | 指定轮播图容器高度 |
+| springConfig | ❌ | {damping: 100} | Animated.WithSpringConfig | 配置动画效果 |
+| onSnapToItem | ❌ | | (index: number) => void | 切换至另一张轮播图时触发 |
+| onScrollBegin | ❌ | | () => void | 切换动画开始时触发 |
+| onScrollEnd | ❌ | | (previous: number, current: number) => void | 切换动画结束时触发 |
+| panGestureHandlerProps | ❌ | {} | Omit,'onHandlerStateChange'> | PanGestureHandler props |
+| onProgressChange | ❌ | | onProgressChange?: (offsetProgress: number,absoluteProgress: number) => void | 当滚动进度发生变化时触发 `offsetProgress`:总的偏移值 (0 390 780 ...); `absoluteProgress`:转化为 index 的进度变化 (0 1 2 ...) |
## Ref
diff --git a/example/src/App.tsx b/example/src/App.tsx
index 19319f1e..b287adf8 100644
--- a/example/src/App.tsx
+++ b/example/src/App.tsx
@@ -32,6 +32,7 @@ export default function App() {
>
+ defaultIndex={1}
ref={r}
width={width}
data={data}
diff --git a/src/Carousel.tsx b/src/Carousel.tsx
index 4c797c43..3467592e 100644
--- a/src/Carousel.tsx
+++ b/src/Carousel.tsx
@@ -17,10 +17,11 @@ import Animated, {
import { CarouselItem } from './CarouselItem';
import type { TMode } from './layouts';
import { ParallaxLayout } from './layouts/index';
-import { useCarouselController } from './useCarouselController';
-import { useComputedAnim } from './useComputedAnim';
-import { useAutoPlay } from './useAutoPlay';
-import { useIndexController } from './useIndexController';
+import { useCarouselController } from './hooks/useCarouselController';
+import { useComputedAnim } from './hooks/useComputedAnim';
+import { useAutoPlay } from './hooks/useAutoPlay';
+import { useIndexController } from './hooks/useIndexController';
+import { usePropsErrorBoundary } from './hooks/usePropsErrorBoundary';
const defaultSpringConfig: Animated.WithSpringConfig = {
damping: 100,
@@ -37,10 +38,6 @@ export interface ICarouselProps {
* @default 'default'
*/
mode?: TMode;
- /**
- * Render carousel item.
- */
- renderItem: (data: T, index: number) => React.ReactNode;
/**
* Specified carousel container width.
*/
@@ -54,6 +51,11 @@ export interface ICarouselProps {
* Carousel items data set.
*/
data: T[];
+ /**
+ * Default index
+ * @default 0
+ */
+ defaultIndex?: number;
/**
* Auto play
*/
@@ -93,6 +95,10 @@ export interface ICarouselProps {
Partial,
'onHandlerStateChange'
>;
+ /**
+ * Render carousel item.
+ */
+ renderItem: (data: T, index: number) => React.ReactNode;
/**
* Callback fired when navigating to an item
*/
@@ -140,6 +146,7 @@ function Carousel(
ref: React.Ref
) {
const {
+ defaultIndex = 0,
height = '100%',
data: _data = [],
loop = true,
@@ -156,12 +163,32 @@ function Carousel(
onProgressChange,
} = props;
+ usePropsErrorBoundary({
+ ...props,
+ defaultIndex,
+ height,
+ data: _data,
+ loop,
+ mode,
+ autoPlay,
+ autoPlayReverse,
+ autoPlayInterval,
+ parallaxScrollingOffset,
+ parallaxScrollingScale,
+ style,
+ panGestureHandlerProps,
+ // @ts-ignore
+ renderItem,
+ onSnapToItem,
+ onProgressChange,
+ });
+
const timingConfig = {
...defaultSpringConfig,
...props.springConfig,
};
const width = Math.round(props.width);
- const handlerOffsetX = useSharedValue(0);
+ const handlerOffsetX = useSharedValue(defaultIndex * width);
const data = React.useMemo(() => {
if (!loop) return _data;
diff --git a/src/CarouselItem.tsx b/src/CarouselItem.tsx
index 2dcf6a49..d12e82da 100644
--- a/src/CarouselItem.tsx
+++ b/src/CarouselItem.tsx
@@ -1,8 +1,8 @@
import React from 'react';
import { FlexStyle, View } from 'react-native';
import Animated, { useAnimatedStyle } from 'react-native-reanimated';
-import type { IComputedAnimResult } from './useComputedAnim';
-import { useOffsetX } from './useOffsetX';
+import type { IComputedAnimResult } from './hooks/useComputedAnim';
+import { useOffsetX } from './hooks/useOffsetX';
export const CarouselItem: React.FC<{
loop?: boolean;
diff --git a/src/useAutoPlay.ts b/src/hooks/useAutoPlay.ts
similarity index 100%
rename from src/useAutoPlay.ts
rename to src/hooks/useAutoPlay.ts
diff --git a/src/useCarouselController.tsx b/src/hooks/useCarouselController.tsx
similarity index 100%
rename from src/useCarouselController.tsx
rename to src/hooks/useCarouselController.tsx
diff --git a/src/useComputedAnim.ts b/src/hooks/useComputedAnim.ts
similarity index 100%
rename from src/useComputedAnim.ts
rename to src/hooks/useComputedAnim.ts
diff --git a/src/useIndexController.ts b/src/hooks/useIndexController.ts
similarity index 100%
rename from src/useIndexController.ts
rename to src/hooks/useIndexController.ts
diff --git a/src/useOffsetX.ts b/src/hooks/useOffsetX.ts
similarity index 100%
rename from src/useOffsetX.ts
rename to src/hooks/useOffsetX.ts
diff --git a/src/hooks/usePropsErrorBoundary.ts b/src/hooks/usePropsErrorBoundary.ts
new file mode 100644
index 00000000..562a84f2
--- /dev/null
+++ b/src/hooks/usePropsErrorBoundary.ts
@@ -0,0 +1,15 @@
+import React from 'react';
+import type { ICarouselProps } from 'src/Carousel';
+
+export function usePropsErrorBoundary(props: ICarouselProps) {
+ React.useEffect(() => {
+ const { defaultIndex, data } = props;
+ if (typeof defaultIndex === 'number') {
+ if (defaultIndex < 0 || defaultIndex >= data.length) {
+ throw Error(
+ 'DefaultIndex must be in the range of data length.'
+ );
+ }
+ }
+ }, [props]);
+}
diff --git a/src/layouts/ParallaxLayout.tsx b/src/layouts/ParallaxLayout.tsx
index 8cdf134d..e21f078c 100644
--- a/src/layouts/ParallaxLayout.tsx
+++ b/src/layouts/ParallaxLayout.tsx
@@ -6,8 +6,8 @@ import Animated, {
interpolate,
useAnimatedStyle,
} from 'react-native-reanimated';
-import type { IComputedAnimResult } from 'src/useComputedAnim';
-import { useOffsetX } from '../useOffsetX';
+import type { IComputedAnimResult } from 'src/hooks/useComputedAnim';
+import { useOffsetX } from '../hooks/useOffsetX';
export const ParallaxLayout: React.FC<{
loop?: boolean;