Skip to content

Commit ba56a09

Browse files
committed
docs: add curve animation
1 parent 00e2955 commit ba56a09

File tree

8 files changed

+320
-16
lines changed

8 files changed

+320
-16
lines changed

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ English | [简体中文](./README.zh-CN.md)
3333
| <img src="assets/left-align.gif"/> |
3434
| <a href="./exampleExpo/src/left-align/index.tsx">left-align</a> |
3535

36-
blur-parallax
3736

3837
> Now you can make cool animations with us! Very easy! [[Details]](./docs/custom-animation.md)
3938
@@ -46,8 +45,8 @@ blur-parallax
4645
| <a href="./exampleExpo/src/marquee/index.tsx">marquee</a> | <a href="./exampleExpo/src/multiple/index.tsx">multiple</a> | <a href="./exampleExpo/src/circular/index.tsx">circular</a> |
4746
| <img src="assets/fold.gif"/> | <img src="assets/tear.gif"/> | <img src="assets/press-swipe.gif"/> |
4847
| <a href="./exampleExpo/src/fold/index.tsx">fold</a> | <a href="./exampleExpo/src/tear/index.tsx">tear</a> | <a href="./exampleExpo/src/press-swipe/index.tsx">press-swipe</a> |
49-
| <img src="assets/cube-3d.gif"/> | <img src="assets/blur-parallax.gif"/> | |
50-
| <a href="./exampleExpo/src/cube-3d/index.tsx">cube-3d</a> | <a href="./exampleExpo/src/blur-parallax/index.tsx">blur-parallax</a> | |
48+
| <img src="assets/cube-3d.gif"/> | <img src="assets/blur-parallax.gif"/> | <img src="assets/curve.gif"/> |
49+
| <a href="./exampleExpo/src/cube-3d/index.tsx">cube-3d</a> | <a href="./exampleExpo/src/blur-parallax/index.tsx">blur-parallax</a> | <a href="./exampleExpo/src/curve/index.tsx">curve</a> |
5150
| <img src="assets/parallax-layers.gif"/> | <img src="assets/stack-cards.gif"/> | <img src="assets/flow.gif"/> |
5251
| <a href="./exampleExpo/src/parallax-layers/index.tsx">parallax-layers</a> | <a href="./exampleExpo/src/stack-cards/index.tsx">stack-cards</a> | <a href="./exampleExpo/src/flow/index.tsx">flow</a> |
5352

README.zh-CN.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
| <a href="./exampleExpo/src/marquee/index.tsx">marquee</a> | <a href="./exampleExpo/src/multiple/index.tsx">multiple</a> | <a href="./exampleExpo/src/circular/index.tsx">circular</a> |
4545
| <img src="assets/fold.gif"/> | <img src="assets/tear.gif"/> | <img src="assets/press-swipe.gif"/> |
4646
| <a href="./exampleExpo/src/fold/index.tsx">fold</a> | <a href="./exampleExpo/src/tear/index.tsx">tear</a> | <a href="./exampleExpo/src/press-swipe/index.tsx">press-swipe</a> |
47-
| <img src="assets/cube-3d.gif"/> | <img src="assets/blur-parallax.gif"/> | |
48-
| <a href="./exampleExpo/src/cube-3d/index.tsx">cube-3d</a> | <a href="./exampleExpo/src/blur-parallax/index.tsx">blur-parallax</a> | |
47+
| <img src="assets/cube-3d.gif"/> | <img src="assets/blur-parallax.gif"/> | <img src="assets/curve.gif"/> |
48+
| <a href="./exampleExpo/src/cube-3d/index.tsx">cube-3d</a> | <a href="./exampleExpo/src/blur-parallax/index.tsx">blur-parallax</a> | <a href="./exampleExpo/src/curve/index.tsx">curve</a> |
4949
| <img src="assets/parallax-layers.gif"/> | <img src="assets/stack-cards.gif"/> | <img src="assets/flow.gif"/> |
5050
| <a href="./exampleExpo/src/parallax-layers/index.tsx">parallax-layers</a> | <a href="./exampleExpo/src/stack-cards/index.tsx">stack-cards</a> | <a href="./exampleExpo/src/flow/index.tsx">flow</a> |
5151

assets/curve.gif

1010 KB
Loading

exampleExpo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
4646
"@babel/runtime": "^7.9.6",
4747
"@expo/webpack-config": "^0.17.0",
48-
"@types/react": "~18.0.0",
48+
"@types/react": "~17.0.0",
4949
"@types/react-native-snap-carousel": "^3.8.5",
5050
"babel-plugin-inline-dotenv": "^1.6.0",
5151
"babel-plugin-module-resolver": "^4.1.0",

exampleExpo/src/Home.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import MultipleComponent from './multiple';
2525
import Flow from './flow';
2626
import Cube3D from './cube-3d';
2727
import BlurParallax from './blur-parallax';
28+
import Curve from './curve';
2829
import PressSwipe from './press-swipe';
2930
import Fold from './fold';
3031
import Tear from './tear';
@@ -60,6 +61,10 @@ export const LayoutsPage = [
6061
];
6162

6263
export const CustomAnimations = [
64+
{
65+
name: 'Curve',
66+
page: Curve,
67+
},
6368
{
6469
name: 'BlurParallax',
6570
page: BlurParallax,

exampleExpo/src/curve/index.tsx

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
import * as React from 'react';
2+
import { View } from 'react-native';
3+
import Carousel from 'react-native-reanimated-carousel';
4+
import Animated, {
5+
Extrapolate,
6+
interpolate,
7+
useAnimatedStyle,
8+
useSharedValue,
9+
} from 'react-native-reanimated';
10+
import SButton from '../components/SButton';
11+
import { SBItem } from '../components/SBItem';
12+
import { ElementsText, window } from '../constants';
13+
import { withAnchorPoint } from '../utils/anchor-point';
14+
15+
const PAGE_WIDTH = window.width / 5;
16+
const colors = [
17+
'#26292E',
18+
'#899F9C',
19+
'#B3C680',
20+
'#5C6265',
21+
'#F5D399',
22+
'#F1F1F1',
23+
];
24+
25+
function Index() {
26+
const [autoPlay, setAutoPlay] = React.useState(false);
27+
const progressValue = useSharedValue<number>(0);
28+
const baseOptions = {
29+
vertical: false,
30+
width: PAGE_WIDTH,
31+
height: PAGE_WIDTH * 0.6,
32+
} as const;
33+
34+
return (
35+
<View
36+
style={{
37+
alignItems: 'center',
38+
}}
39+
>
40+
<View
41+
style={{
42+
position: 'absolute',
43+
width: 50,
44+
height: 51,
45+
backgroundColor: 'white',
46+
borderRadius: 35,
47+
transform: [{ scaleX: 10 }, { scaleY: 2 }],
48+
zIndex: 2,
49+
}}
50+
/>
51+
<View
52+
style={{
53+
position: 'absolute',
54+
width: 50,
55+
height: 51,
56+
backgroundColor: 'white',
57+
borderRadius: 35,
58+
transform: [{ scaleX: 10 }, { scaleY: 2 }],
59+
zIndex: 2,
60+
top: 145,
61+
}}
62+
/>
63+
<Carousel
64+
{...baseOptions}
65+
loop
66+
style={{
67+
height: window.width / 2,
68+
width: window.width,
69+
justifyContent: 'center',
70+
alignItems: 'center',
71+
}}
72+
autoPlay={autoPlay}
73+
autoPlayInterval={150}
74+
scrollAnimationDuration={600}
75+
onProgressChange={(_, absoluteProgress) =>
76+
(progressValue.value = absoluteProgress)
77+
}
78+
customAnimation={(value: number) => {
79+
'worklet';
80+
const size = PAGE_WIDTH;
81+
const scale = interpolate(
82+
value,
83+
[-2, -1, 0, 1, 2],
84+
[1.7, 1.2, 1, 1.2, 1.7],
85+
Extrapolate.CLAMP
86+
);
87+
88+
const translate = interpolate(
89+
value,
90+
[-2, -1, 0, 1, 2],
91+
[-size * 1.45, -size * 0.9, 0, size * 0.9, size * 1.45]
92+
);
93+
94+
const transform = {
95+
transform: [
96+
{ scale },
97+
{
98+
translateX: translate,
99+
},
100+
{ perspective: 150 },
101+
{
102+
rotateY: `${interpolate(
103+
value,
104+
[-1, 0, 1],
105+
[30, 0, -30],
106+
Extrapolate.CLAMP
107+
)}deg`,
108+
},
109+
],
110+
};
111+
112+
return {
113+
...withAnchorPoint(
114+
transform,
115+
{ x: 0.5, y: 0.5 },
116+
{
117+
width: baseOptions.width,
118+
height: baseOptions.height,
119+
}
120+
),
121+
};
122+
}}
123+
modeConfig={{
124+
parallaxScrollingScale: 0.9,
125+
parallaxScrollingOffset: 50,
126+
}}
127+
data={colors}
128+
renderItem={({ index }) => <SBItem index={index} />}
129+
/>
130+
{!!progressValue && (
131+
<View
132+
style={{
133+
flexDirection: 'row',
134+
justifyContent: 'space-between',
135+
width: 100,
136+
marginTop: 10,
137+
alignSelf: 'center',
138+
}}
139+
>
140+
{colors.map((backgroundColor, index) => {
141+
return (
142+
<PaginationItem
143+
backgroundColor={backgroundColor}
144+
animValue={progressValue}
145+
index={index}
146+
key={index}
147+
length={colors.length}
148+
/>
149+
);
150+
})}
151+
</View>
152+
)}
153+
<SButton
154+
onPress={() => setAutoPlay(!autoPlay)}
155+
>{`${ElementsText.AUTOPLAY}:${autoPlay}`}</SButton>
156+
</View>
157+
);
158+
}
159+
160+
const PaginationItem: React.FC<{
161+
index: number;
162+
backgroundColor: string;
163+
length: number;
164+
animValue: Animated.SharedValue<number>;
165+
isRotate?: boolean;
166+
}> = (props) => {
167+
const { animValue, index, length, backgroundColor, isRotate } = props;
168+
const width = 10;
169+
170+
const animStyle = useAnimatedStyle(() => {
171+
let inputRange = [index - 1, index, index + 1];
172+
let outputRange = [-width, 0, width];
173+
174+
if (index === 0 && animValue?.value > length - 1) {
175+
inputRange = [length - 1, length, length + 1];
176+
outputRange = [-width, 0, width];
177+
}
178+
179+
return {
180+
transform: [
181+
{
182+
translateX: interpolate(
183+
animValue?.value,
184+
inputRange,
185+
outputRange,
186+
Extrapolate.CLAMP
187+
),
188+
},
189+
],
190+
};
191+
}, [animValue, index, length]);
192+
return (
193+
<View
194+
style={{
195+
backgroundColor: 'white',
196+
width,
197+
height: width,
198+
borderRadius: 50,
199+
overflow: 'hidden',
200+
transform: [
201+
{
202+
rotateZ: isRotate ? '90deg' : '0deg',
203+
},
204+
],
205+
}}
206+
>
207+
<Animated.View
208+
style={[
209+
{
210+
borderRadius: 50,
211+
backgroundColor,
212+
flex: 1,
213+
},
214+
animStyle,
215+
]}
216+
/>
217+
</View>
218+
);
219+
};
220+
221+
export default Index;

exampleExpo/src/curve/parallax.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { Extrapolate, interpolate } from 'react-native-reanimated';
2+
import type { IComputedDirectionTypes } from 'react-native-reanimated-carousel';
3+
4+
type TBaseConfig = {
5+
size: number;
6+
vertical: boolean;
7+
};
8+
9+
export interface ILayoutConfig {
10+
/**
11+
* control prev/next item offset.
12+
* @default 100
13+
*/
14+
parallaxScrollingOffset?: number;
15+
/**
16+
* control prev/current/next item offset.
17+
* @default 0.8
18+
*/
19+
parallaxScrollingScale?: number;
20+
/**
21+
* control prev/next item offset.
22+
* @default Math.pow(parallaxScrollingScale, 2)
23+
*/
24+
parallaxAdjacentItemScale?: number;
25+
}
26+
27+
export type TParallaxModeProps = IComputedDirectionTypes<{
28+
/**
29+
* Carousel Animated transitions.
30+
*/
31+
mode?: 'parallax';
32+
modeConfig?: ILayoutConfig;
33+
}>;
34+
35+
export function parallaxLayout(
36+
baseConfig: TBaseConfig,
37+
modeConfig: ILayoutConfig = {}
38+
) {
39+
const { size, vertical } = baseConfig;
40+
const {
41+
parallaxScrollingOffset = 100,
42+
parallaxScrollingScale = 0.8,
43+
parallaxAdjacentItemScale = Math.pow(parallaxScrollingScale, 2),
44+
} = modeConfig;
45+
46+
return (value: number) => {
47+
'worklet';
48+
const translate = interpolate(
49+
value,
50+
[-1, 0, 1],
51+
[-size + parallaxScrollingOffset, 0, size - parallaxScrollingOffset]
52+
);
53+
54+
const zIndex = interpolate(
55+
value,
56+
[-1, 0, 1],
57+
[0, size, 0],
58+
Extrapolate.CLAMP
59+
);
60+
61+
const scale = interpolate(
62+
value,
63+
[-1, 0, 1],
64+
[
65+
parallaxAdjacentItemScale,
66+
parallaxScrollingScale,
67+
parallaxAdjacentItemScale,
68+
],
69+
Extrapolate.CLAMP
70+
);
71+
72+
return {
73+
transform: [
74+
vertical
75+
? {
76+
translateY: translate,
77+
}
78+
: {
79+
translateX: translate,
80+
},
81+
{
82+
scale,
83+
},
84+
],
85+
zIndex,
86+
};
87+
};
88+
}

exampleExpo/yarn.lock

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,7 +2180,7 @@
21802180
dependencies:
21812181
"@types/react" "*"
21822182

2183-
"@types/react@*", "@types/react@^17":
2183+
"@types/react@*", "@types/react@^17", "@types/react@~17.0.0":
21842184
version "17.0.48"
21852185
resolved "https://registry.npmjs.org/@types/react/-/react-17.0.48.tgz#a4532a8b91d7b27b8768b6fc0c3bccb760d15a6c"
21862186
integrity sha512-zJ6IYlJ8cYYxiJfUaZOQee4lh99mFihBoqkOSEGV+dFi9leROW6+PgstzQ+w3gWTnUfskALtQPGHK6dYmPj+2A==
@@ -2189,15 +2189,6 @@
21892189
"@types/scheduler" "*"
21902190
csstype "^3.0.2"
21912191

2192-
"@types/react@~18.0.0":
2193-
version "18.0.15"
2194-
resolved "https://registry.npmjs.org/@types/react/-/react-18.0.15.tgz#d355644c26832dc27f3e6cbf0c4f4603fc4ab7fe"
2195-
integrity sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow==
2196-
dependencies:
2197-
"@types/prop-types" "*"
2198-
"@types/scheduler" "*"
2199-
csstype "^3.0.2"
2200-
22012192
"@types/responselike@*", "@types/responselike@^1.0.0":
22022193
version "1.0.0"
22032194
resolved "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"

0 commit comments

Comments
 (0)