Skip to content

Commit 8cf14e0

Browse files
authored
Merge pull request #39 from dohooo/alpha-1.0.5
Alpha 1.0.5
2 parents e288a9c + 0597a14 commit 8cf14e0

File tree

4 files changed

+110
-60
lines changed

4 files changed

+110
-60
lines changed

example/src/App.tsx

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
/* eslint-disable react-native/no-inline-styles */
22
import * as React from 'react';
3-
import { Dimensions, Image, ImageSourcePropType, View } from 'react-native';
3+
import {
4+
Button,
5+
Dimensions,
6+
Image,
7+
ImageSourcePropType,
8+
View,
9+
} from 'react-native';
410
import Carousel from '../../src/index';
511
import type { ICarouselInstance } from '../../src/Carousel';
612
import Animated, {
@@ -10,7 +16,7 @@ import Animated, {
1016
useSharedValue,
1117
} from 'react-native-reanimated';
1218

13-
const { width } = Dimensions.get('window');
19+
const window = Dimensions.get('window');
1420

1521
const data: ImageSourcePropType[] = [
1622
require('../assets/carousel-0.jpg'),
@@ -21,6 +27,7 @@ const data: ImageSourcePropType[] = [
2127
export default function App() {
2228
const progressValue = useSharedValue<number>(0);
2329
const r = React.useRef<ICarouselInstance | null>(null);
30+
2431
return (
2532
<View
2633
style={{
@@ -30,11 +37,11 @@ export default function App() {
3037
paddingTop: 100,
3138
}}
3239
>
33-
<View style={{ height: 300 }}>
40+
<View style={{ height: 240 }}>
3441
<Carousel<ImageSourcePropType>
3542
defaultIndex={1}
3643
ref={r}
37-
width={width}
44+
width={window.width}
3845
data={data}
3946
parallaxScrollingScale={0.8}
4047
renderItem={(source) => (
@@ -50,13 +57,33 @@ export default function App() {
5057
)}
5158
/>
5259
</View>
53-
<View style={{ height: 300 }}>
60+
<View
61+
style={{
62+
marginTop: 24,
63+
flexDirection: 'row',
64+
justifyContent: 'space-evenly',
65+
}}
66+
>
67+
<Button
68+
title="Prev"
69+
onPress={() => {
70+
r.current?.prev();
71+
}}
72+
/>
73+
<Button
74+
title="Next"
75+
onPress={() => {
76+
r.current?.next();
77+
}}
78+
/>
79+
</View>
80+
<View style={{ height: 240 }}>
5481
<Carousel<ImageSourcePropType>
5582
onProgressChange={(_, absoluteProgress) => {
5683
progressValue.value = absoluteProgress;
5784
}}
5885
mode="parallax"
59-
width={width}
86+
width={window.width}
6087
data={data}
6188
parallaxScrollingScale={0.8}
6289
renderItem={(source) => (

src/Carousel.tsx

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ function Carousel<T extends unknown = any>(
188188
...props.springConfig,
189189
};
190190
const width = Math.round(props.width);
191-
const handlerOffsetX = useSharedValue<number>(defaultIndex * width);
191+
const defaultHandlerOffsetX = -Math.abs(defaultIndex * width);
192+
const handlerOffsetX = useSharedValue<number>(defaultHandlerOffsetX);
192193
const data = React.useMemo<T[]>(() => {
193194
if (!loop) return _data;
194195

@@ -247,8 +248,12 @@ function Carousel<T extends unknown = any>(
247248

248249
const offsetX = useDerivedValue(() => {
249250
const x = handlerOffsetX.value % computedAnimResult.TOTAL_WIDTH;
251+
252+
if (!loop) {
253+
return handlerOffsetX.value;
254+
}
250255
return isNaN(x) ? 0 : x;
251-
}, [computedAnimResult]);
256+
}, [computedAnimResult, loop]);
252257

253258
useAnimatedReaction(
254259
() => offsetX.value,
@@ -322,14 +327,23 @@ function Carousel<T extends unknown = any>(
322327
}
323328

324329
const page = Math.round(handlerOffsetX.value / width);
330+
325331
const velocityPage = Math.round(
326332
(handlerOffsetX.value + e.velocityX) / width
327333
);
328-
const pageWithVelocity = Math.min(
334+
335+
let pageWithVelocity = Math.min(
329336
page + 1,
330337
Math.max(page - 1, velocityPage)
331338
);
332339

340+
if (!loop) {
341+
pageWithVelocity = Math.max(
342+
-(data.length - 1),
343+
Math.min(0, pageWithVelocity)
344+
);
345+
}
346+
333347
if (loop) {
334348
handlerOffsetX.value = _withAnimationCallback(
335349
pageWithVelocity * width
@@ -367,48 +381,52 @@ function Carousel<T extends unknown = any>(
367381
[getCurrentIndex, goToIndex, next, prev]
368382
);
369383

370-
const Layouts = React.useMemo<React.FC<{ index: number }>>(() => {
371-
switch (mode) {
372-
case 'parallax':
373-
return ({ index: i, children }) => (
374-
<ParallaxLayout
375-
parallaxScrollingOffset={parallaxScrollingOffset}
376-
parallaxScrollingScale={parallaxScrollingScale}
377-
computedAnimResult={computedAnimResult}
378-
width={width}
379-
handlerOffsetX={offsetX}
380-
index={i}
381-
key={i}
382-
loop={loop}
383-
>
384-
{children}
385-
</ParallaxLayout>
386-
);
387-
default:
388-
return ({ index: i, children }) => (
389-
<CarouselItem
390-
computedAnimResult={computedAnimResult}
391-
width={width}
392-
height={height}
393-
handlerOffsetX={offsetX}
394-
index={i}
395-
key={i}
396-
loop={loop}
397-
>
398-
{children}
399-
</CarouselItem>
400-
);
401-
}
402-
}, [
403-
loop,
404-
mode,
405-
computedAnimResult,
406-
height,
407-
offsetX,
408-
parallaxScrollingOffset,
409-
parallaxScrollingScale,
410-
width,
411-
]);
384+
const renderLayout = React.useCallback(
385+
(item: T, i: number) => {
386+
switch (mode) {
387+
case 'parallax':
388+
return (
389+
<ParallaxLayout
390+
parallaxScrollingOffset={parallaxScrollingOffset}
391+
parallaxScrollingScale={parallaxScrollingScale}
392+
computedAnimResult={computedAnimResult}
393+
width={width}
394+
handlerOffsetX={offsetX}
395+
index={i}
396+
key={i}
397+
loop={loop}
398+
>
399+
{renderItem(item, i)}
400+
</ParallaxLayout>
401+
);
402+
default:
403+
return (
404+
<CarouselItem
405+
computedAnimResult={computedAnimResult}
406+
width={width}
407+
height={height}
408+
handlerOffsetX={offsetX}
409+
index={i}
410+
key={i}
411+
loop={loop}
412+
>
413+
{renderItem(item, i)}
414+
</CarouselItem>
415+
);
416+
}
417+
},
418+
[
419+
loop,
420+
mode,
421+
computedAnimResult,
422+
height,
423+
offsetX,
424+
parallaxScrollingOffset,
425+
parallaxScrollingScale,
426+
width,
427+
renderItem,
428+
]
429+
);
412430

413431
return (
414432
<PanGestureHandler
@@ -425,13 +443,7 @@ function Carousel<T extends unknown = any>(
425443
position: 'relative',
426444
}}
427445
>
428-
{data.map((item, i) => {
429-
return (
430-
<Layouts index={i} key={i}>
431-
{renderItem(item, i)}
432-
</Layouts>
433-
);
434-
})}
446+
{data.map(renderLayout)}
435447
</Animated.View>
436448
</PanGestureHandler>
437449
);

src/hooks/useCarouselController.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ export function useCarouselController(opts: IOpts): ICarouselController {
5454

5555
onScrollBegin?.();
5656

57+
const currentPage = Math.round(handlerOffsetX.value / width);
58+
5759
handlerOffsetX.value = withTiming(
58-
handlerOffsetX.value - width,
60+
(currentPage - 1) * width,
5961
defaultTimingConfig,
6062
(isFinished: boolean) => {
6163
if (isFinished) {
@@ -79,8 +81,10 @@ export function useCarouselController(opts: IOpts): ICarouselController {
7981

8082
onScrollBegin?.();
8183

84+
const currentPage = Math.round(handlerOffsetX.value / width);
85+
8286
handlerOffsetX.value = withTiming(
83-
handlerOffsetX.value + width,
87+
(currentPage + 1) * width,
8488
defaultTimingConfig,
8589
(isFinished: boolean) => {
8690
if (isFinished) {

src/utils/log.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* In worklet
3+
* e.g. runOnJS(lop)(...);
4+
*/
5+
export function log(msg: any) {
6+
console.log(msg);
7+
}

0 commit comments

Comments
 (0)