Skip to content

Commit

Permalink
Merge pull request #39 from dohooo/alpha-1.0.5
Browse files Browse the repository at this point in the history
Alpha 1.0.5
  • Loading branch information
gxxgcn authored Nov 20, 2021
2 parents e288a9c + 0597a14 commit 8cf14e0
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 60 deletions.
39 changes: 33 additions & 6 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
/* eslint-disable react-native/no-inline-styles */
import * as React from 'react';
import { Dimensions, Image, ImageSourcePropType, View } from 'react-native';
import {
Button,
Dimensions,
Image,
ImageSourcePropType,
View,
} from 'react-native';
import Carousel from '../../src/index';
import type { ICarouselInstance } from '../../src/Carousel';
import Animated, {
Expand All @@ -10,7 +16,7 @@ import Animated, {
useSharedValue,
} from 'react-native-reanimated';

const { width } = Dimensions.get('window');
const window = Dimensions.get('window');

const data: ImageSourcePropType[] = [
require('../assets/carousel-0.jpg'),
Expand All @@ -21,6 +27,7 @@ const data: ImageSourcePropType[] = [
export default function App() {
const progressValue = useSharedValue<number>(0);
const r = React.useRef<ICarouselInstance | null>(null);

return (
<View
style={{
Expand All @@ -30,11 +37,11 @@ export default function App() {
paddingTop: 100,
}}
>
<View style={{ height: 300 }}>
<View style={{ height: 240 }}>
<Carousel<ImageSourcePropType>
defaultIndex={1}
ref={r}
width={width}
width={window.width}
data={data}
parallaxScrollingScale={0.8}
renderItem={(source) => (
Expand All @@ -50,13 +57,33 @@ export default function App() {
)}
/>
</View>
<View style={{ height: 300 }}>
<View
style={{
marginTop: 24,
flexDirection: 'row',
justifyContent: 'space-evenly',
}}
>
<Button
title="Prev"
onPress={() => {
r.current?.prev();
}}
/>
<Button
title="Next"
onPress={() => {
r.current?.next();
}}
/>
</View>
<View style={{ height: 240 }}>
<Carousel<ImageSourcePropType>
onProgressChange={(_, absoluteProgress) => {
progressValue.value = absoluteProgress;
}}
mode="parallax"
width={width}
width={window.width}
data={data}
parallaxScrollingScale={0.8}
renderItem={(source) => (
Expand Down
116 changes: 64 additions & 52 deletions src/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ function Carousel<T extends unknown = any>(
...props.springConfig,
};
const width = Math.round(props.width);
const handlerOffsetX = useSharedValue<number>(defaultIndex * width);
const defaultHandlerOffsetX = -Math.abs(defaultIndex * width);
const handlerOffsetX = useSharedValue<number>(defaultHandlerOffsetX);
const data = React.useMemo<T[]>(() => {
if (!loop) return _data;

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

const offsetX = useDerivedValue(() => {
const x = handlerOffsetX.value % computedAnimResult.TOTAL_WIDTH;

if (!loop) {
return handlerOffsetX.value;
}
return isNaN(x) ? 0 : x;
}, [computedAnimResult]);
}, [computedAnimResult, loop]);

useAnimatedReaction(
() => offsetX.value,
Expand Down Expand Up @@ -322,14 +327,23 @@ function Carousel<T extends unknown = any>(
}

const page = Math.round(handlerOffsetX.value / width);

const velocityPage = Math.round(
(handlerOffsetX.value + e.velocityX) / width
);
const pageWithVelocity = Math.min(

let pageWithVelocity = Math.min(
page + 1,
Math.max(page - 1, velocityPage)
);

if (!loop) {
pageWithVelocity = Math.max(
-(data.length - 1),
Math.min(0, pageWithVelocity)
);
}

if (loop) {
handlerOffsetX.value = _withAnimationCallback(
pageWithVelocity * width
Expand Down Expand Up @@ -367,48 +381,52 @@ function Carousel<T extends unknown = any>(
[getCurrentIndex, goToIndex, next, prev]
);

const Layouts = React.useMemo<React.FC<{ index: number }>>(() => {
switch (mode) {
case 'parallax':
return ({ index: i, children }) => (
<ParallaxLayout
parallaxScrollingOffset={parallaxScrollingOffset}
parallaxScrollingScale={parallaxScrollingScale}
computedAnimResult={computedAnimResult}
width={width}
handlerOffsetX={offsetX}
index={i}
key={i}
loop={loop}
>
{children}
</ParallaxLayout>
);
default:
return ({ index: i, children }) => (
<CarouselItem
computedAnimResult={computedAnimResult}
width={width}
height={height}
handlerOffsetX={offsetX}
index={i}
key={i}
loop={loop}
>
{children}
</CarouselItem>
);
}
}, [
loop,
mode,
computedAnimResult,
height,
offsetX,
parallaxScrollingOffset,
parallaxScrollingScale,
width,
]);
const renderLayout = React.useCallback(
(item: T, i: number) => {
switch (mode) {
case 'parallax':
return (
<ParallaxLayout
parallaxScrollingOffset={parallaxScrollingOffset}
parallaxScrollingScale={parallaxScrollingScale}
computedAnimResult={computedAnimResult}
width={width}
handlerOffsetX={offsetX}
index={i}
key={i}
loop={loop}
>
{renderItem(item, i)}
</ParallaxLayout>
);
default:
return (
<CarouselItem
computedAnimResult={computedAnimResult}
width={width}
height={height}
handlerOffsetX={offsetX}
index={i}
key={i}
loop={loop}
>
{renderItem(item, i)}
</CarouselItem>
);
}
},
[
loop,
mode,
computedAnimResult,
height,
offsetX,
parallaxScrollingOffset,
parallaxScrollingScale,
width,
renderItem,
]
);

return (
<PanGestureHandler
Expand All @@ -425,13 +443,7 @@ function Carousel<T extends unknown = any>(
position: 'relative',
}}
>
{data.map((item, i) => {
return (
<Layouts index={i} key={i}>
{renderItem(item, i)}
</Layouts>
);
})}
{data.map(renderLayout)}
</Animated.View>
</PanGestureHandler>
);
Expand Down
8 changes: 6 additions & 2 deletions src/hooks/useCarouselController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ export function useCarouselController(opts: IOpts): ICarouselController {

onScrollBegin?.();

const currentPage = Math.round(handlerOffsetX.value / width);

handlerOffsetX.value = withTiming(
handlerOffsetX.value - width,
(currentPage - 1) * width,
defaultTimingConfig,
(isFinished: boolean) => {
if (isFinished) {
Expand All @@ -79,8 +81,10 @@ export function useCarouselController(opts: IOpts): ICarouselController {

onScrollBegin?.();

const currentPage = Math.round(handlerOffsetX.value / width);

handlerOffsetX.value = withTiming(
handlerOffsetX.value + width,
(currentPage + 1) * width,
defaultTimingConfig,
(isFinished: boolean) => {
if (isFinished) {
Expand Down
7 changes: 7 additions & 0 deletions src/utils/log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* In worklet
* e.g. runOnJS(lop)(...);
*/
export function log(msg: any) {
console.log(msg);
}

0 comments on commit 8cf14e0

Please sign in to comment.