├── .watchmanconfig
├── .gitignore
├── app.json
├── .DS_Store
├── demo2.gif
├── assets
├── .DS_Store
├── dublin.jpg
├── seville.jpg
├── venice.jpg
├── amsterdam.jpg
├── dublinAvatar.png
├── veniceAvatar.jpg
├── amsterdamAvatar.jpg
└── sevilleAvatar.jpg
├── ParallexSwiper
├── index.js
├── styles.js
└── ParallexSwiper.js
├── .babelrc
├── App.test.js
├── App.js
├── package.json
├── README.md
├── data.js
└── .flowconfig
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .expo/
3 | npm-debug.*
4 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "sdkVersion": "21.0.0"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/.DS_Store
--------------------------------------------------------------------------------
/demo2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/demo2.gif
--------------------------------------------------------------------------------
/assets/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/assets/.DS_Store
--------------------------------------------------------------------------------
/assets/dublin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/assets/dublin.jpg
--------------------------------------------------------------------------------
/assets/seville.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/assets/seville.jpg
--------------------------------------------------------------------------------
/assets/venice.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/assets/venice.jpg
--------------------------------------------------------------------------------
/assets/amsterdam.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/assets/amsterdam.jpg
--------------------------------------------------------------------------------
/assets/dublinAvatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/assets/dublinAvatar.png
--------------------------------------------------------------------------------
/assets/veniceAvatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/assets/veniceAvatar.jpg
--------------------------------------------------------------------------------
/ParallexSwiper/index.js:
--------------------------------------------------------------------------------
1 | import ParallexSwiper from './ParallexSwiper';
2 |
3 | export default ParallexSwiper;
4 |
--------------------------------------------------------------------------------
/assets/amsterdamAvatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/assets/amsterdamAvatar.jpg
--------------------------------------------------------------------------------
/assets/sevilleAvatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sankhadeeproy007/CardAnimation/HEAD/assets/sevilleAvatar.jpg
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["babel-preset-expo"],
3 | "env": {
4 | "development": {
5 | "plugins": ["transform-react-jsx-source"]
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import App from './App';
3 |
4 | import renderer from 'react-test-renderer';
5 |
6 | it('renders without crashing', () => {
7 | const rendered = renderer.create().toJSON();
8 | expect(rendered).toBeTruthy();
9 | });
10 |
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { StyleSheet, View } from 'react-native';
3 | import ParallexSwiper from './ParallexSwiper';
4 | import data from './data';
5 |
6 | export default class App extends React.Component {
7 | render() {
8 | return (
9 |
10 |
11 |
12 | );
13 | }
14 | }
15 |
16 | const styles = StyleSheet.create({
17 | container: {
18 | paddingTop: 20,
19 | flex: 1,
20 | justifyContent: 'center',
21 | alignItems: 'center',
22 | },
23 | });
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "CardAnimate",
3 | "version": "0.1.0",
4 | "private": true,
5 | "devDependencies": {
6 | "react-native-scripts": "1.5.0",
7 | "jest-expo": "^21.0.2",
8 | "react-test-renderer": "16.0.0-alpha.12"
9 | },
10 | "main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
11 | "scripts": {
12 | "start": "react-native-scripts start",
13 | "eject": "react-native-scripts eject",
14 | "android": "react-native-scripts android",
15 | "ios": "react-native-scripts ios",
16 | "test": "node node_modules/jest/bin/jest.js --watch"
17 | },
18 | "jest": {
19 | "preset": "jest-expo"
20 | },
21 | "dependencies": {
22 | "expo": "^21.0.0",
23 | "react": "16.0.0-alpha.12",
24 | "react-native": "^0.48.4"
25 | }
26 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ParallexSwiper in react-native!
2 | 
3 |
4 |
5 | `` takes `data` as a prop (built on top of react-native FlatList).
6 | Shape of `data` object is
7 | ```
8 | {
9 | name: '',
10 | cover: require(''),
11 | avatar: require(''),
12 | cardTitle: '',
13 | cardText: '',
14 | },
15 | ```
16 | `cover` and `avatar` are images.
17 |
18 | ## Example
19 | ```
20 | import ParallexSwiper from './ParallexSwiper';
21 |
22 | export default class App extends React.Component {
23 | render() {
24 | return (
25 |
26 | );
27 | }
28 | }
29 | ```
30 |
31 | ### To-do
32 | * Make card configurable (support images)
33 | * Animated duration and easing functions as props
34 |
35 |
36 | _Laggy gif is due to low fps of gif recorder_
37 |
--------------------------------------------------------------------------------
/ParallexSwiper/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet, Dimensions } from 'react-native';
2 | const { width, height } = Dimensions.get('window');
3 | const styles = StyleSheet.create({
4 | container: {
5 | paddingTop: 20,
6 | flex: 1,
7 | justifyContent: 'center',
8 | alignItems: 'center',
9 | },
10 | item: {
11 | width: width,
12 | height: height,
13 | flex: 1,
14 | justifyContent: 'center',
15 | alignItems: 'center',
16 | },
17 | touchableHeight: {
18 | height: height * 0.8,
19 | width: width * 0.8,
20 | borderRadius: 10,
21 | },
22 | shadowContainer: {
23 | borderRadius: 10,
24 | shadowColor: '#000',
25 | shadowOffset: {
26 | width: 0,
27 | height: 3,
28 | },
29 | shadowOpacity: 0.27,
30 | shadowRadius: 4.65,
31 | },
32 | innerShadow: {
33 | height: '60%',
34 | overflow: 'hidden',
35 | borderTopRightRadius: 10,
36 | borderTopLeftRadius: 10,
37 | },
38 | coverImage: {
39 | width: '100%',
40 | height: '100%',
41 | },
42 | innerAnimated: {
43 | justifyContent: 'center',
44 | alignItems: 'center',
45 | marginTop: 20,
46 | },
47 | avatar: {
48 | width: 80,
49 | height: 80,
50 | borderRadius: 40,
51 | },
52 | title: {
53 | fontSize: 18,
54 | marginTop: 8,
55 | color: '#303030',
56 | },
57 | animatedCard: {
58 | justifyContent: 'center',
59 | alignItems: 'center',
60 | alignSelf: 'center',
61 | backgroundColor: '#fff',
62 | height: 200,
63 | width: 375,
64 | },
65 | innerCard: {
66 | borderRadius: 5,
67 | shadowColor: '#000',
68 | shadowOffset: {
69 | width: 0,
70 | height: 3,
71 | },
72 | shadowOpacity: 0.27,
73 | shadowRadius: 4.65,
74 | height: 200,
75 | width: 220,
76 | },
77 | cardTitle: { textAlign: 'center', marginTop: 12 },
78 | cardText: { color: '#626262', fontSize: 12 },
79 | cardPadding: { padding: 12 },
80 | });
81 |
82 | export default styles;
83 |
--------------------------------------------------------------------------------
/data.js:
--------------------------------------------------------------------------------
1 | const data = [
2 | {
3 | name: 'Venice',
4 | cover: require('./assets/venice.jpg'),
5 | avatar: require('./assets/veniceAvatar.jpg'),
6 | cardTitle: 'Venice',
7 | cardText:
8 | 'Venice, the capital of northern Italy’s Veneto region, is built on more than 100 small islands in a lagoon in the Adriatic Sea. It has no roads, just canals – including the Grand Canal thoroughfare – lined with Renaissance and Gothic palaces.',
9 | },
10 | {
11 | name: 'Seville',
12 | cover: require('./assets/seville.jpg'),
13 | avatar: require('./assets/sevilleAvatar.jpg'),
14 | cardTitle: 'Seville',
15 | cardText:
16 | 'Seville is the capital of southern Spain’s Andalusia region. It is famous for flamenco dancing, particularly in its Triana neighborhood. Major landmarks include the ornate Alcázar castle complex, built during the Moorish Almohad dynasty, and the 18th-century Plaza de Toros de la Maestranza bullring.',
17 | },
18 | {
19 | name: 'Amsterdam',
20 | cover: require('./assets/amsterdam.jpg'),
21 | avatar: require('./assets/amsterdamAvatar.jpg'),
22 | cardTitle: 'Amsterdam',
23 | cardText:
24 | 'Amsterdam is the Netherlands capital, known for its artistic heritage, elaborate canal system and narrow houses with gabled facades, legacies of the city’s 17th-century Golden Age. Its Museum District houses the Van Gogh Museum, works by Vermeer at the Rijksmuseum, and modern art at the Stedelijk.',
25 | },
26 | {
27 | name: 'Dublin',
28 | cover: require('./assets/dublin.jpg'),
29 | avatar: require('./assets/dublinAvatar.png'),
30 | cardTitle: 'Dublin',
31 | cardText:
32 | 'Dublin, capital of the Republic of Ireland, is on Ireland’s east coast at the mouth of the River Liffey. Its historic buildings include Dublin Castle, dating to the 13th century, and imposing St Patrick’s Cathedral, founded in 1191. City parks include landscaped St Stephen’s Green and huge Phoenix Park.',
33 | },
34 | ];
35 |
36 | export default data;
37 |
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | ; We fork some components by platform
3 | .*/*[.]android.js
4 |
5 | ; Ignore "BUCK" generated dirs
6 | /\.buckd/
7 |
8 | ; Ignore unexpected extra "@providesModule"
9 | .*/node_modules/.*/node_modules/fbjs/.*
10 |
11 | ; Ignore duplicate module providers
12 | ; For RN Apps installed via npm, "Libraries" folder is inside
13 | ; "node_modules/react-native" but in the source repo it is in the root
14 | .*/Libraries/react-native/React.js
15 | .*/Libraries/react-native/ReactNative.js
16 |
17 | ; Additional create-react-native-app ignores
18 |
19 | ; Ignore duplicate module providers
20 | .*/node_modules/fbemitter/lib/*
21 |
22 | ; Ignore misbehaving dev-dependencies
23 | .*/node_modules/xdl/build/*
24 | .*/node_modules/reqwest/tests/*
25 |
26 | ; Ignore missing expo-sdk dependencies (temporarily)
27 | ; https://github.com/expo/expo/issues/162
28 | .*/node_modules/expo/src/*
29 |
30 | ; Ignore react-native-fbads dependency of the expo sdk
31 | .*/node_modules/react-native-fbads/*
32 |
33 | [include]
34 |
35 | [libs]
36 | node_modules/react-native/Libraries/react-native/react-native-interface.js
37 | node_modules/react-native/flow
38 | flow/
39 |
40 | [options]
41 | module.system=haste
42 |
43 | emoji=true
44 |
45 | experimental.strict_type_args=true
46 |
47 | munge_underscores=true
48 |
49 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
50 |
51 | suppress_type=$FlowIssue
52 | suppress_type=$FlowFixMe
53 | suppress_type=$FixMe
54 |
55 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
56 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
57 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
58 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
59 |
60 | unsafe.enable_getters_and_setters=true
61 |
62 | [version]
63 | ^0.49.1
64 |
--------------------------------------------------------------------------------
/ParallexSwiper/ParallexSwiper.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | StyleSheet,
4 | Text,
5 | View,
6 | FlatList,
7 | Dimensions,
8 | Animated,
9 | Image,
10 | TouchableOpacity,
11 | } from 'react-native';
12 | import styles from './styles';
13 |
14 | const { width, height } = Dimensions.get('window');
15 |
16 | const AnimatedList = Animated.createAnimatedComponent(FlatList);
17 |
18 | const getInterpolate = (animatedScroll, i) => {
19 | const inputRange = [i - 1 * width, i * width, (i + 1) * width];
20 |
21 | const outputRange = i === 0 ? [0, 0, 110] : [-300, 0, 110];
22 |
23 | return animatedScroll.interpolate({
24 | inputRange,
25 | outputRange,
26 | extrapolate: 'clamp',
27 | });
28 | };
29 |
30 | export default class App extends React.Component {
31 | constructor(props) {
32 | super(props);
33 | this.state = {
34 | currentPage: 0,
35 | scrollDisabled: false,
36 | };
37 | }
38 | imageParallex = new Animated.Value(0);
39 | coverScale = new Animated.Value(0);
40 | animate() {
41 | if (!this.state.scrollDisabled) {
42 | Animated.timing(this.coverScale, {
43 | toValue: 1,
44 | duration: 300,
45 | useNativeDriver: true,
46 | }).start();
47 | } else {
48 | Animated.timing(this.coverScale, {
49 | toValue: 0,
50 | duration: 300,
51 | useNativeDriver: true,
52 | }).start();
53 | }
54 | this.setState({
55 | scrollDisabled: !this.state.scrollDisabled,
56 | });
57 | }
58 | opacity = this.coverScale.interpolate({
59 | inputRange: [0, 0.5, 1],
60 | outputRange: [1, 0.15, 0],
61 | extrapolate: 'clamp',
62 | });
63 | translateY = this.coverScale.interpolate({
64 | inputRange: [0, 0.5, 1],
65 | outputRange: [150, 50, -155],
66 | extrapolate: 'clamp',
67 | });
68 | scale = this.coverScale.interpolate({
69 | inputRange: [0, 0.5, 1],
70 | outputRange: [1, 1.12, 1.25],
71 | extrapolate: 'clamp',
72 | });
73 | render() {
74 | return (
75 | item.name}
88 | scrollEventThrottle={1}
89 | renderItem={({ item, index }) => (
90 |
99 | this.animate()}
102 | style={styles.touchableHeight}
103 | >
104 |
105 |
106 |
119 |
120 |
128 |
129 | {item.name}
130 |
131 |
132 |
144 |
145 | {item.cardTitle}
146 |
147 | {item.cardText}
148 |
149 |
150 |
151 |
152 |
153 | )}
154 | />
155 | );
156 | }
157 | }
158 |
--------------------------------------------------------------------------------