├── .babelrc
├── .eslintrc
├── .gitignore
├── .watchmanconfig
├── assets
├── icons
│ ├── app.png
│ └── loading.png
└── screenshots
│ └── demo.png
├── exp.json
├── jsconfig.json
├── main.js
├── package.json
├── readme.md
├── src
├── App.js
├── Navigator.js
├── animations
│ ├── AnimatedBasic.js
│ ├── BouncingHeart.js
│ ├── CollapseHeader.js
│ ├── ColorBox.js
│ ├── CommentModal.js
│ ├── EventCard.js
│ ├── FloatingHeart.js
│ ├── MagicButton.js
│ ├── MagicCard.js
│ ├── MagicInput.js
│ ├── ParallaxScrollview.js
│ ├── SpringyMenu.js
│ ├── assets
│ │ └── images
│ │ │ ├── 1.jpeg
│ │ │ ├── 2.jpg
│ │ │ ├── 3.jpeg
│ │ │ ├── 4.jpeg
│ │ │ └── beansable.png
│ └── components
│ │ ├── heart.js
│ │ └── moment.js
├── components
│ ├── Info.js
│ ├── List.js
│ └── StatusBar.js
└── icons
│ ├── BackIcon.js
│ ├── HelpIcon.js
│ ├── MenuIcon.js
│ ├── OpenIcon.js
│ └── ShareIcon.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["babel-preset-expo"],
3 | "env": {
4 | "development": {
5 | "plugins": ["transform-react-jsx-source"]
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "equimper"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/**/*
2 | .expo/*
3 | npm-debug.*
4 | .vscode/
5 | .DS_Store
--------------------------------------------------------------------------------
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/assets/icons/app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bkdev98/react-native-animation-examples/2ee8721f771cb4ab1872d5a29828d8bc916fb41d/assets/icons/app.png
--------------------------------------------------------------------------------
/assets/icons/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bkdev98/react-native-animation-examples/2ee8721f771cb4ab1872d5a29828d8bc916fb41d/assets/icons/loading.png
--------------------------------------------------------------------------------
/assets/screenshots/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bkdev98/react-native-animation-examples/2ee8721f771cb4ab1872d5a29828d8bc916fb41d/assets/screenshots/demo.png
--------------------------------------------------------------------------------
/exp.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-animations",
3 | "description": "An empty new project",
4 | "slug": "react-native-animations",
5 | "privacy": "public",
6 | "sdkVersion": "16.0.0",
7 | "version": "1.0.0",
8 | "orientation": "portrait",
9 | "primaryColor": "#cccccc",
10 | "icon": "./assets/icons/app.png",
11 | "loading": {
12 | "icon": "./assets/icons/loading.png",
13 | "hideExponentText": false
14 | },
15 | "packagerOpts": {
16 | "assetExts": ["ttf", "mp4"]
17 | },
18 | "ios": {
19 | "supportsTablet": true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true,
4 | "allowSyntheticDefaultImports": true
5 | },
6 | "exclude": [
7 | "node_modules"
8 | ]
9 | }
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | import Expo from 'expo';
2 |
3 | import App from './src/App';
4 |
5 | Expo.registerRootComponent(App);
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-animations",
3 | "version": "0.0.0",
4 | "description": "Hello Expo!",
5 | "author": null,
6 | "private": true,
7 | "main": "main.js",
8 | "dependencies": {
9 | "expo": "16.0.0",
10 | "react": "16.0.0-alpha.6",
11 | "react-native": "https://github.com/expo/react-native/archive/sdk-16.0.0.tar.gz",
12 | "react-navigation": "^1.0.0-beta.11"
13 | },
14 | "devDependencies": {
15 | "eslint": "^4.0.0",
16 | "eslint-config-equimper": "^2.1.2"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # React Native Animations Collection
2 | > A beautiful collection of React Native animations linked with Github 🐬.
3 |
4 |
5 | ## Demo
6 | - Published App using Expo: [https://exp.host/@bkdev/react-native-animations](https://exp.host/@bkdev/react-native-animations)
7 | - Standalone App: `Comming Soon!`
8 |
9 | ## Development
10 | This app was wrapped using [Expo](https://expo.io).
11 | Clone the repo, `yarn`, `exp start`, `exp ios` then open folder with any [code](http://blog.bkdev.me/2017/04/11/vscode.html) editors and you are ready to have fun 🍻.
12 |
13 | I just made the whole stuffs in one day so feel free making issues and pull requests, you are so welcome! 🙌🏻
14 |
15 | ## Tutorials
16 | Comming soon on [Beansable Team](https://beansable.com).
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View } from 'react-native';
3 |
4 | import Navigator from './Navigator';
5 | import StatusBar from './components/StatusBar';
6 |
7 | const App = () => (
8 |
9 |
10 |
11 |
12 | );
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/src/Navigator.js:
--------------------------------------------------------------------------------
1 | import {
2 | StackNavigator,
3 | } from 'react-navigation';
4 |
5 | import List from './components/List';
6 | import AnimatedBasic from './animations/AnimatedBasic';
7 | import MagicButton from './animations/MagicButton';
8 | import MagicCard from './animations/MagicCard';
9 | import ColorBox from './animations/ColorBox';
10 | import ParallaxScrollview from './animations/ParallaxScrollview';
11 | import BouncingHeart from './animations/BouncingHeart';
12 | import SpringyMenu from './animations/SpringyMenu';
13 | import CommentModal from './animations/CommentModal';
14 | import FloatingHeart from './animations/FloatingHeart';
15 | import EventCard from './animations/EventCard';
16 | import CollapseHeader from './animations/CollapseHeader';
17 | import MagicInput from './animations/MagicInput';
18 |
19 | const Navigator = StackNavigator({
20 | List: { screen: List },
21 | AnimatedBasic: { screen: AnimatedBasic },
22 | MagicButton: { screen: MagicButton },
23 | MagicCard: { screen: MagicCard },
24 | ColorBox: { screen: ColorBox },
25 | ParallaxScrollview: { screen: ParallaxScrollview },
26 | BouncingHeart: { screen: BouncingHeart },
27 | SpringyMenu: { screen: SpringyMenu },
28 | CommentModal: { screen: CommentModal },
29 | FloatingHeart: { screen: FloatingHeart },
30 | EventCard: { screen: EventCard },
31 | CollapseHeader: { screen: CollapseHeader },
32 | MagicInput: { screen: MagicInput },
33 | });
34 |
35 | export default Navigator;
36 |
--------------------------------------------------------------------------------
/src/animations/AnimatedBasic.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | StyleSheet,
5 | Animated,
6 | Easing,
7 | Linking,
8 | } from 'react-native';
9 |
10 | import BackIcon from '../icons/BackIcon';
11 | import OpenIcon from '../icons/OpenIcon';
12 |
13 | class AnimatedBasic extends Component {
14 | static navigationOptions = ({ navigation }) => ({
15 | headerTitle: 'Animated Basic',
16 | headerStyle: {
17 | height: 80,
18 | backgroundColor: '#EC407A',
19 | justifyContent: 'center',
20 | },
21 | headerTitleStyle: {
22 | color: 'white',
23 | fontSize: 20,
24 | fontWeight: '400',
25 | },
26 | headerLeft: navigation.goBack()} />,
27 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/AnimatedBasic.js')} />,
28 | })
29 |
30 | componentWillMount() {
31 | this.animatedValue = new Animated.Value(100);
32 | }
33 |
34 | componentDidMount() {
35 | Animated.timing(this.animatedValue, {
36 | toValue: 150,
37 | duration: 3000,
38 | easing: Easing.bounce,
39 | }).start();
40 | }
41 |
42 | render() {
43 | const animatedStyle = { height: this.animatedValue };
44 | return (
45 |
46 |
47 |
48 | );
49 | }
50 | }
51 |
52 | const styles = StyleSheet.create({
53 | container: {
54 | flex: 1,
55 | justifyContent: 'center',
56 | alignItems: 'center',
57 | },
58 | root: {
59 | width: 100,
60 | height: 100,
61 | backgroundColor: '#b1bb',
62 | },
63 | });
64 |
65 | export default AnimatedBasic;
66 |
--------------------------------------------------------------------------------
/src/animations/BouncingHeart.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | StyleSheet,
5 | Animated,
6 | TouchableWithoutFeedback,
7 | Linking,
8 | } from 'react-native';
9 |
10 | import BackIcon from '../icons/BackIcon';
11 | import OpenIcon from '../icons/OpenIcon';
12 | import Heart from './components/heart';
13 |
14 | const getTransformationAnimation = (animation, scale, y, x, rotate, opacity) => {
15 | const scaleAnimation = animation.interpolate({
16 | inputRange: [0, 1],
17 | outputRange: [0, scale],
18 | });
19 |
20 | const xAnimation = animation.interpolate({
21 | inputRange: [0, 1],
22 | outputRange: [0, x],
23 | });
24 |
25 | const yAnimation = animation.interpolate({
26 | inputRange: [0, 1],
27 | outputRange: [0, y],
28 | });
29 |
30 | const rotateAnimation = animation.interpolate({
31 | inputRange: [0, 1],
32 | outputRange: ['0deg', rotate],
33 | });
34 |
35 | const opacityAnimation = animation.interpolate({
36 | inputRange: [0, 1],
37 | outputRange: [0, opacity],
38 | });
39 |
40 | return {
41 | opacity: opacityAnimation,
42 | transform: [
43 | { scale: scaleAnimation },
44 | { translateX: xAnimation },
45 | { translateY: yAnimation },
46 | { rotate: rotateAnimation },
47 | ],
48 | };
49 | };
50 |
51 | class BouncingHeart extends Component {
52 | static navigationOptions = ({ navigation }) => ({
53 | headerTitle: 'Bouncing Heart',
54 | headerStyle: {
55 | height: 80,
56 | backgroundColor: '#EC407A',
57 | justifyContent: 'center',
58 | },
59 | headerTitleStyle: {
60 | color: 'white',
61 | fontSize: 20,
62 | fontWeight: '400',
63 | },
64 | headerLeft: navigation.goBack()} />,
65 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/BouncingHeart.js')} />,
66 | })
67 |
68 | constructor(props) {
69 | super(props);
70 | this.state = {
71 | liked: false,
72 | scale: new Animated.Value(0),
73 | animations: [
74 | new Animated.Value(0),
75 | new Animated.Value(0),
76 | new Animated.Value(0),
77 | new Animated.Value(0),
78 | new Animated.Value(0),
79 | new Animated.Value(0),
80 | ],
81 | };
82 | }
83 |
84 | triggerLike = () => {
85 | this.setState({
86 | liked: !this.state.liked,
87 | });
88 |
89 | const showAnimations = this.state.animations.map((animation) => Animated.spring(animation, {
90 | toValue: 1,
91 | friction: 4,
92 | }));
93 |
94 | const hideAnimations = this.state.animations.map((animation) => Animated.timing(animation, {
95 | toValue: 0,
96 | duration: 50,
97 | })).reverse();
98 |
99 | Animated.parallel([
100 | Animated.spring(this.state.scale, {
101 | toValue: 2,
102 | friction: 3,
103 | }),
104 | Animated.sequence([
105 | Animated.stagger(50, showAnimations),
106 | Animated.delay(100),
107 | Animated.stagger(50, hideAnimations),
108 | ]),
109 | ]).start(() => {
110 | this.state.scale.setValue(0);
111 | });
112 | }
113 |
114 | render() {
115 | const bouncyHeart = this.state.scale.interpolate({
116 | inputRange: [0, 1, 2],
117 | outputRange: [1, 0.8, 1],
118 | });
119 |
120 | const heartButtonStyle = {
121 | transform: [
122 | { scale: bouncyHeart },
123 | ],
124 | };
125 |
126 | return (
127 |
128 |
129 |
133 |
137 |
141 |
145 |
149 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 | );
161 | }
162 | }
163 |
164 | const styles = StyleSheet.create({
165 | container: {
166 | flex: 1,
167 | justifyContent: 'center',
168 | alignItems: 'center',
169 | },
170 | heart: {
171 | position: 'absolute',
172 | top: 0,
173 | left: 0,
174 | },
175 | });
176 |
177 | export default BouncingHeart;
178 |
--------------------------------------------------------------------------------
/src/animations/CollapseHeader.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | Animated,
5 | StyleSheet,
6 | Linking,
7 | Text,
8 | ScrollView,
9 | } from 'react-native';
10 |
11 | import Beansable from './assets/images/beansable.png';
12 | import BackIcon from '../icons/BackIcon';
13 | import OpenIcon from '../icons/OpenIcon';
14 |
15 | class CollapseHeader extends Component {
16 | static navigationOptions = ({ navigation }) => ({
17 | headerTitle: 'Collapse Header',
18 | headerStyle: {
19 | height: 80,
20 | backgroundColor: '#EC407A',
21 | justifyContent: 'center',
22 | },
23 | headerTitleStyle: {
24 | color: 'white',
25 | fontSize: 20,
26 | fontWeight: '400',
27 | },
28 | headerLeft: navigation.goBack()} />,
29 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/CollapseHeader.js')} />,
30 | })
31 |
32 | componentWillMount() {
33 | this.animated = new Animated.Value(0);
34 | }
35 |
36 | render() {
37 | const hideImageInterpolate = this.animated.interpolate({
38 | inputRange: [0, 150],
39 | outputRange: [50, 0],
40 | extrapolate: 'clamp',
41 | });
42 |
43 | const fontInterpolate = this.animated.interpolate({
44 | inputRange: [0, 150],
45 | outputRange: [15, 20],
46 | });
47 |
48 | const opacityInterpolate = this.animated.interpolate({
49 | inputRange: [0, 150],
50 | outputRange: [1, 0],
51 | extrapolate: 'clamp',
52 | });
53 |
54 | const collapseInterpolate = this.animated.interpolate({
55 | inputRange: [0, 150],
56 | outputRange: [30, 0],
57 | extrapolate: 'clamp',
58 | });
59 |
60 | const imageStyle = {
61 | width: hideImageInterpolate,
62 | height: hideImageInterpolate,
63 | };
64 |
65 | const titleStyle = {
66 | fontSize: fontInterpolate,
67 | };
68 |
69 | const fadeButtonStyle = {
70 | opacity: opacityInterpolate,
71 | height: collapseInterpolate,
72 | };
73 |
74 | return (
75 |
76 |
77 |
78 | Beansable
79 |
80 |
81 | Articles
82 |
83 |
84 | Contact
85 |
86 |
87 |
88 |
89 |
95 |
96 | top
97 |
98 |
99 |
100 |
101 | );
102 | }
103 | }
104 |
105 | const styles = StyleSheet.create({
106 | container: {
107 | flex: 1,
108 | },
109 | header: {
110 | backgroundColor: '#F06292',
111 | alignItems: 'center',
112 | padding: 10,
113 | },
114 | logoImage: {
115 | width: 50,
116 | height: 50,
117 | },
118 | title: {
119 | color: 'rgba(255,255,255,.8)',
120 | fontSize: 15,
121 | },
122 | buttons: {
123 | flexDirection: 'row',
124 | },
125 | button: {
126 | flex: 5,
127 | justifyContent: 'center',
128 | alignItems: 'center',
129 | },
130 | buttonText: {
131 | color: 'rgba(255,255,255,.5)',
132 | fontSize: 15,
133 | },
134 | scrollView: {
135 | },
136 | fakeContent: {
137 | padding: 20,
138 | height: 800,
139 | alignItems: 'center',
140 | },
141 | fakeText: {
142 | fontSize: 25,
143 | color: '#F8BBD0',
144 | },
145 | });
146 |
147 | export default CollapseHeader;
148 |
--------------------------------------------------------------------------------
/src/animations/ColorBox.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | Animated,
5 | StyleSheet,
6 | Linking,
7 | } from 'react-native';
8 |
9 | import BackIcon from '../icons/BackIcon';
10 | import OpenIcon from '../icons/OpenIcon';
11 |
12 | class ColorBox extends Component {
13 | static navigationOptions = ({ navigation }) => ({
14 | headerTitle: 'Color Box',
15 | headerStyle: {
16 | height: 80,
17 | backgroundColor: '#EC407A',
18 | justifyContent: 'center',
19 | },
20 | headerTitleStyle: {
21 | color: 'white',
22 | fontSize: 20,
23 | fontWeight: '400',
24 | },
25 | headerLeft: navigation.goBack()} />,
26 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/ColorBox.js')} />,
27 | })
28 |
29 | componentWillMount() {
30 | this.animatedValue = new Animated.Value(0);
31 | }
32 |
33 | componentDidMount() {
34 | Animated.timing(this.animatedValue, {
35 | toValue: 150,
36 | duration: 1500,
37 | }).start();
38 | }
39 |
40 | render() {
41 | const interpolateColor = this.animatedValue.interpolate({
42 | inputRange: [0, 150],
43 | outputRange: ['#FCE4EC', '#E91E63'],
44 | });
45 |
46 | const animatedStyle = {
47 | backgroundColor: interpolateColor,
48 | transform: [
49 | { translateY: this.animatedValue },
50 | ],
51 | };
52 |
53 | return (
54 |
55 |
56 |
57 | );
58 | }
59 | }
60 |
61 | const styles = StyleSheet.create({
62 | container: {
63 | flex: 1,
64 | justifyContent: 'center',
65 | alignItems: 'center',
66 | },
67 | box: {
68 | width: 100,
69 | height: 100,
70 | },
71 | });
72 |
73 | export default ColorBox;
74 |
--------------------------------------------------------------------------------
/src/animations/CommentModal.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | Animated,
5 | StyleSheet,
6 | Linking,
7 | ScrollView,
8 | Text,
9 | TextInput,
10 | PanResponder,
11 | } from 'react-native';
12 |
13 | import BackIcon from '../icons/BackIcon';
14 | import OpenIcon from '../icons/OpenIcon';
15 |
16 | class CommentModal extends Component {
17 | static navigationOptions = ({ navigation }) => ({
18 | headerTitle: 'Comment Modal',
19 | headerStyle: {
20 | height: 80,
21 | backgroundColor: '#EC407A',
22 | justifyContent: 'center',
23 | },
24 | headerTitleStyle: {
25 | color: 'white',
26 | fontSize: 20,
27 | fontWeight: '400',
28 | },
29 | headerLeft: navigation.goBack()} />,
30 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/CommentModal.js')} />,
31 | })
32 |
33 | componentWillMount() {
34 | this.animated = new Animated.Value(0);
35 | this.animatedMargin = new Animated.Value(0);
36 | this.scrollOffset = 0;
37 | this.contentHeight = 0;
38 | this.scrollViewHeight = 0;
39 |
40 | this.panResponder = PanResponder.create({
41 | onMoveShouldSetPanResponder: (evt, gestureState) => {
42 | const { dy } = gestureState;
43 | const totalScrollHeight = this.scrollOffset + this.scrollViewHeight;
44 |
45 | if (
46 | (this.scrollOffset <= 0 && dy > 0) ||
47 | ((totalScrollHeight >= this.contentHeight) && dy < 0)
48 | ) return true;
49 | },
50 | onPanResponderMove: (e, gestureState) => {
51 | const { dy } = gestureState;
52 | if (dy < 0) {
53 | this.animated.setValue(dy);
54 | } else if (dy > 0) {
55 | this.animatedMargin.setValue(dy);
56 | }
57 | },
58 | onPanResponderRelease: (e, gestureState) => {
59 | const { dy } = gestureState;
60 |
61 | if (dy < -150) {
62 | Animated.parallel([
63 | Animated.timing(this.animated, {
64 | toValue: -550,
65 | duration: 150,
66 | }),
67 | Animated.timing(this.animatedMargin, {
68 | toValue: 0,
69 | duration: 150,
70 | }),
71 | ]).start();
72 | } else if (dy > -150 && dy < 150) {
73 | Animated.parallel([
74 | Animated.timing(this.animated, {
75 | toValue: 0,
76 | duration: 150,
77 | }),
78 | Animated.timing(this.animatedMargin, {
79 | toValue: 0,
80 | duration: 150,
81 | }),
82 | ]).start();
83 | } else if (dy > 150) {
84 | Animated.timing(this.animated, {
85 | toValue: 550,
86 | duration: 300,
87 | }).start();
88 | }
89 | },
90 | });
91 | }
92 |
93 | render() {
94 | const spacerStyle = {
95 | marginTop: this.animatedMargin,
96 | };
97 |
98 | const opacityInterpolate = this.animated.interpolate({
99 | inputRange: [-500, 0, 500],
100 | outputRange: [0, 1, 0],
101 | });
102 |
103 | const modalStyle = {
104 | transform: [
105 | { translateY: this.animated },
106 | ],
107 | opacity: opacityInterpolate,
108 | };
109 |
110 | return (
111 |
112 |
113 |
117 |
118 | {
121 | this.scrollOffset = event.nativeEvent.contentOffset.y;
122 | this.scrollViewHeight = event.nativeEvent.layoutMeasurement.height;
123 | }}
124 | onContentSizeChange={(contentWidth, contentHeight) => {
125 | this.contentHeight = contentHeight;
126 | }}
127 | >
128 | Top
129 |
130 | Bottom
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | );
139 | }
140 | }
141 |
142 | const styles = StyleSheet.create({
143 | container: {
144 | flex: 1,
145 | justifyContent: 'center',
146 | alignItems: 'center',
147 | },
148 | modal: {
149 | width: 350,
150 | height: 500,
151 | borderColor: '#F8BBD0',
152 | borderWidth: 2,
153 | },
154 | comments: {
155 | flex: 9.5,
156 | },
157 | fakeComments: {
158 | height: 500,
159 | },
160 | fakeText: {
161 | textAlign: 'center',
162 | color: '#F06292',
163 | fontSize: 20,
164 | paddingVertical: 8,
165 | backgroundColor: 'white',
166 | },
167 | inputWrap: {
168 | flex: 0.5,
169 | justifyContent: 'center',
170 | backgroundColor: 'white',
171 | padding: 20,
172 | },
173 | });
174 |
175 | export default CommentModal;
176 |
--------------------------------------------------------------------------------
/src/animations/EventCard.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | StyleSheet,
5 | Animated,
6 | Linking,
7 | Text,
8 | Image,
9 | TouchableOpacity,
10 | ScrollView,
11 | } from 'react-native';
12 |
13 | import BackIcon from '../icons/BackIcon';
14 | import OpenIcon from '../icons/OpenIcon';
15 |
16 | import Unsplash from './assets/images/4.jpeg';
17 |
18 | class EventCard extends Component {
19 | static navigationOptions = ({ navigation }) => ({
20 | headerTitle: 'Event Card',
21 | headerStyle: {
22 | height: 80,
23 | backgroundColor: '#EC407A',
24 | justifyContent: 'center',
25 | },
26 | headerTitleStyle: {
27 | color: 'white',
28 | fontSize: 20,
29 | fontWeight: '400',
30 | },
31 | headerLeft: navigation.goBack()} />,
32 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/EventCard.js')} />,
33 | })
34 |
35 | state = {
36 | open: false,
37 | }
38 |
39 | componentWillMount() {
40 | this.animated = new Animated.Value(0);
41 | }
42 |
43 | toggleCard = () => {
44 | this.setState((state) => ({
45 | open: !state.open,
46 | }), () => {
47 | const toValue = this.state.open ? 1 : 0;
48 | Animated.timing(this.animated, {
49 | toValue,
50 | duration: 500,
51 | }).start();
52 | });
53 | }
54 |
55 | render() {
56 | const offsetInterplate = this.animated.interpolate({
57 | inputRange: [0, 1],
58 | outputRange: [191, 0],
59 | });
60 |
61 | const arrowRotate = this.animated.interpolate({
62 | inputRange: [0, 1],
63 | outputRange: ['180deg', '0deg'],
64 | });
65 |
66 | const offsetStyle = {
67 | transform: [
68 | {
69 | translateY: offsetInterplate,
70 | },
71 | ],
72 | };
73 |
74 | const arrowStyle = {
75 | transform: [
76 | {
77 | rotate: arrowRotate,
78 | },
79 | ],
80 | };
81 |
82 | const opacityStyle = {
83 | opacity: this.animated,
84 | };
85 |
86 | return (
87 |
88 |
89 |
90 |
91 |
92 |
93 | Lets Get It On
94 | Marvin Gaye
95 |
96 |
97 | ↓
98 |
99 |
100 |
101 |
102 |
103 |
104 | Don't you know how sweet and wonderful life can be?
105 | I'm askin' you baby to get it on with me, oh oh
106 | I ain't gonna worry, I ain't gonna push
107 | I won't push you baby
108 | So come on, come on, come on, come on baby
109 | Stop beatin' round the bush, hey
110 | Let's get it on, let's get it on
111 | You know what I'm talkin' 'bout
112 | Come on baby, let your love come out
113 | If you believe in love
114 | Let's get it on, let's get it on baby
115 | This minute, oh yeah let's get it on
116 | Please, let's get it on
117 | I know you know what I been dreamin' of, don't you baby?
118 | My whole body makes that feelin' of love, I'm happy
119 | I ain't gonna worry, no I ain't gonna push
120 | I won't push you baby, woo
121 |
122 |
123 |
124 |
125 |
126 |
127 | );
128 | }
129 | }
130 |
131 | const styles = StyleSheet.create({
132 | container: {
133 | flex: 1,
134 | justifyContent: 'center',
135 | alignItems: 'center',
136 | },
137 | background: {
138 | width: 300,
139 | height: 250,
140 | borderRadius: 3,
141 | overflow: 'hidden',
142 | borderWidth: 3,
143 | borderColor: 'white',
144 | },
145 | scrollViewWrap: {
146 | flex: 1,
147 | paddingTop: 5,
148 | },
149 | contentText: {
150 | fontSize: 16,
151 | color: 'rgba(0,0,0,.5)',
152 | },
153 | card: {
154 | backgroundColor: '#fff',
155 | flex: 1,
156 | paddingHorizontal: 15,
157 | paddingVertical: 4,
158 | transform: [{
159 | translateY: 191,
160 | }],
161 | },
162 | scrollView: {
163 | marginTop: 15,
164 | },
165 | header: {
166 | flexDirection: 'row',
167 | },
168 | title: {
169 | fontSize: 23,
170 | color: '#F06292',
171 | },
172 | description: {
173 | fontSize: 17,
174 | color: '#F48FB1',
175 | },
176 | arrowContainer: {
177 | flex: 1,
178 | alignItems: 'flex-end',
179 | justifyContent: 'center',
180 | },
181 | arrow: {
182 | fontSize: 18,
183 | color: '#F48FB1',
184 | },
185 | });
186 |
187 | export default EventCard;
188 |
--------------------------------------------------------------------------------
/src/animations/FloatingHeart.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | StyleSheet,
5 | Animated,
6 | TouchableWithoutFeedback,
7 | Linking,
8 | Text,
9 | Dimensions,
10 | } from 'react-native';
11 |
12 | import BackIcon from '../icons/BackIcon';
13 | import OpenIcon from '../icons/OpenIcon';
14 |
15 | const { width, height } = Dimensions.get('window');
16 |
17 | const getRandomInt = (min, max) => {
18 | min = Math.ceil(min);
19 | max = Math.floor(max);
20 | return Math.floor(Math.random() * (max - min)) + min; // The maximum is exclusive and the minimum is inclusive
21 | };
22 |
23 | class FloatingHeart extends Component {
24 | static navigationOptions = ({ navigation }) => ({
25 | headerTitle: 'Floating Heart',
26 | headerStyle: {
27 | height: 80,
28 | backgroundColor: '#EC407A',
29 | justifyContent: 'center',
30 | },
31 | headerTitleStyle: {
32 | color: 'white',
33 | fontSize: 20,
34 | fontWeight: '400',
35 | },
36 | headerLeft: navigation.goBack()} />,
37 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/FloatingHeart.js')} />,
38 | })
39 |
40 | state = {
41 | hearts: [],
42 | }
43 |
44 | handleAddHeart = () => {
45 | const animation = new Animated.Value(0);
46 | this.setState((state) => ({
47 | hearts: [
48 | ...state.hearts,
49 | {
50 | animation,
51 | start: getRandomInt(100, width - 100),
52 | },
53 | ],
54 | }), () => {
55 | Animated.timing(animation, {
56 | toValue: height,
57 | duration: 3000,
58 | }).start();
59 | });
60 | }
61 |
62 | render() {
63 | return (
64 |
65 | touch touch
66 |
67 |
68 | {
69 | this.state.hearts.map(({ animation, start }, index) => {
70 | const positionInterpolate = animation.interpolate({
71 | inputRange: [0, height],
72 | outputRange: [height - 50, 0],
73 | });
74 |
75 | const opacityInterpolate = animation.interpolate({
76 | inputRange: [0, height - 200],
77 | outputRange: [1, 0],
78 | });
79 |
80 | const scaleInterpolate = animation.interpolate({
81 | inputRange: [0, 15, 30],
82 | outputRange: [0, 1.2, 1],
83 | extrapolate: 'clamp',
84 | });
85 |
86 | const dividedHeight = height / 6;
87 | const wobbleInterpolate = animation.interpolate({
88 | inputRange: [
89 | 0,
90 | dividedHeight * 1,
91 | dividedHeight * 2,
92 | dividedHeight * 3,
93 | dividedHeight * 4,
94 | dividedHeight * 5,
95 | dividedHeight * 6,
96 | ],
97 | outputRange: [
98 | 0,
99 | 15,
100 | -15,
101 | 15,
102 | -15,
103 | 15,
104 | -15,
105 | ],
106 | extrapolate: 'clamp',
107 | });
108 |
109 | const heartStyle = {
110 | left: start,
111 | transform: [
112 | { translateY: positionInterpolate },
113 | { translateX: wobbleInterpolate },
114 | { scale: scaleInterpolate },
115 | ],
116 | opacity: opacityInterpolate,
117 | };
118 | return ;
119 | })
120 | }
121 |
122 |
123 |
124 | );
125 | }
126 | }
127 |
128 | const Heart = ({ style }) => (
129 |
130 |
131 |
132 |
133 | );
134 |
135 | const styles = StyleSheet.create({
136 | container: {
137 | flex: 1,
138 | alignItems: 'center',
139 | justifyContent: 'center',
140 | },
141 | title: {
142 | color: '#F8BBD0',
143 | backgroundColor: 'transparent',
144 | fontSize: 30,
145 | },
146 | heart: {
147 | width: 50,
148 | height: 50,
149 | position: 'absolute',
150 | },
151 | heartShape: {
152 | width: 30,
153 | height: 45,
154 | position: 'absolute',
155 | top: 0,
156 | borderTopLeftRadius: 15,
157 | borderTopRightRadius: 15,
158 | backgroundColor: '#E91E63',
159 | },
160 | leftHeart: {
161 | transform: [{ rotate: '-45deg' }],
162 | left: 5,
163 | },
164 | rightHeart: {
165 | transform: [{ rotate: '45deg' }],
166 | right: 5,
167 | },
168 | });
169 |
170 | export default FloatingHeart;
171 |
--------------------------------------------------------------------------------
/src/animations/MagicButton.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | Text,
5 | TouchableWithoutFeedback,
6 | Animated,
7 | StyleSheet,
8 | Linking,
9 | } from 'react-native';
10 |
11 | import BackIcon from '../icons/BackIcon';
12 | import OpenIcon from '../icons/OpenIcon';
13 |
14 | class MagicButton extends Component {
15 | static navigationOptions = ({ navigation }) => ({
16 | headerTitle: 'Magic Button',
17 | headerStyle: {
18 | height: 80,
19 | backgroundColor: '#EC407A',
20 | justifyContent: 'center',
21 | },
22 | headerTitleStyle: {
23 | color: 'white',
24 | fontSize: 20,
25 | fontWeight: '400',
26 | },
27 | headerLeft: navigation.goBack()} />,
28 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/MagicButton.js')} />,
29 | })
30 |
31 | constructor(props) {
32 | super(props);
33 |
34 | this.handlePressIn = this.handlePressIn.bind(this);
35 | this.handlePressOut = this.handlePressOut.bind(this);
36 | }
37 |
38 | componentWillMount() {
39 | this.animatedValue = new Animated.Value(1);
40 | }
41 |
42 | handlePressIn() {
43 | Animated.spring(this.animatedValue, {
44 | toValue: 0.5,
45 | }).start();
46 | }
47 |
48 | handlePressOut() {
49 | Animated.spring(this.animatedValue, {
50 | toValue: 1,
51 | friction: 3,
52 | tension: 40,
53 | }).start();
54 | }
55 |
56 | render() {
57 | const animatedStyle = {
58 | transform: [{ scale: this.animatedValue }],
59 | };
60 |
61 | return (
62 |
63 |
67 |
68 | Press Me
69 |
70 |
71 |
72 | );
73 | }
74 | }
75 |
76 | const styles = StyleSheet.create({
77 | container: {
78 | flex: 1,
79 | justifyContent: 'center',
80 | alignItems: 'center',
81 | },
82 | button: {
83 | backgroundColor: '#9C27B0',
84 | width: 100,
85 | height: 50,
86 | alignItems: 'center',
87 | justifyContent: 'center',
88 | borderRadius: 5,
89 | },
90 | text: {
91 | color: '#fff',
92 | },
93 | });
94 |
95 | export default MagicButton;
96 |
--------------------------------------------------------------------------------
/src/animations/MagicCard.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | Text,
4 | View,
5 | Animated,
6 | PanResponder,
7 | StyleSheet,
8 | Linking,
9 | } from 'react-native';
10 |
11 | import BackIcon from '../icons/BackIcon';
12 | import OpenIcon from '../icons/OpenIcon';
13 |
14 | class MagicCard extends Component {
15 | static navigationOptions = ({ navigation }) => ({
16 | headerTitle: 'Magic Card',
17 | headerStyle: {
18 | height: 80,
19 | backgroundColor: '#EC407A',
20 | justifyContent: 'center',
21 | },
22 | headerTitleStyle: {
23 | color: 'white',
24 | fontSize: 20,
25 | fontWeight: '400',
26 | },
27 | headerLeft: navigation.goBack()} />,
28 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/MagicCard.js')} />,
29 | })
30 |
31 | componentWillMount() {
32 | this.animatedValue = new Animated.ValueXY();
33 | this._value = { x: 0, y: 0 };
34 | this.animatedValue.addListener((value) => this._value = value); // eslint-disable-line
35 | this.panResponder = PanResponder.create({
36 | onStartShouldSetPanResponder: (evt, gestureState) => true, // eslint-disable-line
37 | onMoveShouldSetPanResponder: (evt, gestureState) => true, // eslint-disable-line
38 | onPanResponderGrant: (e, gestureState) => { // eslint-disable-line
39 | this.animatedValue.setOffset({
40 | x: this._value.x,
41 | y: this._value.y,
42 | });
43 | this.animatedValue.setValue({ x: 0, y: 0 });
44 | },
45 | onPanResponderMove: Animated.event([
46 | null,
47 | { dx: this.animatedValue.x, dy: this.animatedValue.y },
48 | ]),
49 | onPanResponderRelease: (e, gestureState) => {
50 | this.animatedValue.flattenOffset();
51 | Animated.decay(this.animatedValue, {
52 | deceleration: 0.997,
53 | velocity: { x: gestureState.vx, y: gestureState.vy },
54 | }).start();
55 | },
56 | });
57 | }
58 | render() {
59 | const animatedStyle = {
60 | transform: this.animatedValue.getTranslateTransform(),
61 | };
62 | return (
63 |
64 |
65 | Drag Me
66 |
67 |
68 | );
69 | }
70 | }
71 |
72 | const styles = StyleSheet.create({
73 | container: {
74 | flex: 1,
75 | justifyContent: 'center',
76 | alignItems: 'center',
77 | },
78 | box: {
79 | backgroundColor: '#D81B60',
80 | width: 100,
81 | height: 100,
82 | justifyContent: 'center',
83 | alignItems: 'center',
84 | },
85 | text: {
86 | color: '#fff',
87 | },
88 | });
89 |
90 | export default MagicCard;
91 |
--------------------------------------------------------------------------------
/src/animations/MagicInput.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | Text,
4 | View,
5 | Animated,
6 | TouchableWithoutFeedback,
7 | TouchableOpacity,
8 | TextInput,
9 | StyleSheet,
10 | Linking,
11 | } from 'react-native';
12 |
13 | import BackIcon from '../icons/BackIcon';
14 | import OpenIcon from '../icons/OpenIcon';
15 |
16 | class MagicInput extends Component {
17 | static navigationOptions = ({ navigation }) => ({
18 | headerTitle: 'Magic Input',
19 | headerStyle: {
20 | height: 80,
21 | backgroundColor: '#EC407A',
22 | justifyContent: 'center',
23 | },
24 | headerTitleStyle: {
25 | color: 'white',
26 | fontSize: 20,
27 | fontWeight: '400',
28 | },
29 | headerLeft: navigation.goBack()} />,
30 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/MagicInput.js')} />,
31 | })
32 |
33 | state = {
34 | animated: new Animated.Value(0),
35 | success: false,
36 | }
37 |
38 | handlePress = () => {
39 | Animated.timing(this.state.animated, {
40 | toValue: 1,
41 | duration: 300,
42 | }).start();
43 | }
44 |
45 | handleSend = () => {
46 | this.setState({
47 | success: true,
48 | }, () => {
49 | Animated.sequence([
50 | Animated.timing(this.state.animated, {
51 | toValue: 0,
52 | duration: 300,
53 | }),
54 | Animated.delay(1500),
55 | ]).start(() => this.setState({ success: false }));
56 | });
57 | }
58 |
59 | render() {
60 | const widthInterpolate = this.state.animated.interpolate({
61 | inputRange: [0, 0.5, 1],
62 | outputRange: [150, 150, 300],
63 | extrapolate: 'clamp',
64 | });
65 |
66 | const inputScaleInterpolate = this.state.animated.interpolate({
67 | inputRange: [0, 0.5, 0.6],
68 | outputRange: [0, 0, 1],
69 | extrapolate: 'clamp',
70 | });
71 |
72 | const sendButtonInterpolate = this.state.animated.interpolate({
73 | inputRange: [0, 0.6, 1],
74 | outputRange: [0, 0, 1],
75 | });
76 |
77 | const notifyTextScaleInterpolate = this.state.animated.interpolate({
78 | inputRange: [0, 0.5],
79 | outputRange: [1, 0],
80 | extrapolate: 'clamp',
81 | });
82 |
83 | const thankyouScaleInterpolate = this.state.animated.interpolate({
84 | inputRange: [0, 1],
85 | outputRange: [1, 0],
86 | });
87 |
88 | const thankYouTextStyle = {
89 | transform: [
90 | {
91 | scale: thankyouScaleInterpolate,
92 | },
93 | ],
94 | };
95 |
96 | const inputScaleStyle = {
97 | transform: [
98 | { scale: inputScaleInterpolate },
99 | ],
100 | };
101 |
102 | const buttonWrapStyle = {
103 | width: widthInterpolate,
104 | };
105 |
106 | const sendButtonStyle = {
107 | transform: [
108 | { scale: sendButtonInterpolate },
109 | ],
110 | };
111 |
112 | const notifyTextStyle = {
113 | transform: [
114 | { scale: notifyTextScaleInterpolate },
115 | ],
116 | };
117 |
118 | const { animated, success } = this.state;
119 |
120 | return (
121 |
122 |
123 |
124 | {!success &&
125 |
126 |
134 |
135 | Send
136 |
137 |
138 | }
139 |
140 | {!success &&
141 | Notify Me
142 | }
143 | {success &&
144 | Thank You
145 | }
146 |
147 |
148 |
149 | );
150 | }
151 | }
152 |
153 | const styles = StyleSheet.create({
154 | container: {
155 | flex: 1,
156 | justifyContent: 'center',
157 | alignItems: 'center',
158 | backgroundColor: '#F06292',
159 | },
160 | touchWF: {
161 | borderRadius: 25,
162 | },
163 | buttonWrap: {
164 | position: 'absolute',
165 | height: 50,
166 | backgroundColor: 'white',
167 | borderRadius: 25,
168 | },
169 | sendContainer: {
170 | flex: 1,
171 | position: 'absolute',
172 | justifyContent: 'flex-start',
173 | alignItems: 'center',
174 | flexDirection: 'row',
175 | },
176 | textInput: {
177 | left: 10,
178 | width: 212,
179 | fontSize: 16,
180 | color: '#F06292',
181 | },
182 | placeholderText: {
183 | fontSize: 16,
184 | color: '#F06292',
185 | },
186 | sendButton: {
187 | width: 80,
188 | height: 44,
189 | borderRadius: 22,
190 | backgroundColor: '#F06292',
191 | },
192 | center: {
193 | alignItems: 'center',
194 | justifyContent: 'center',
195 | },
196 | sendText: {
197 | color: 'white',
198 | backgroundColor: 'transparent',
199 | fontSize: 16,
200 | },
201 | notifyText: {
202 | position: 'absolute',
203 | color: '#F06292',
204 | fontWeight: '700',
205 | backgroundColor: 'transparent',
206 | },
207 | });
208 |
209 | export default MagicInput;
210 |
--------------------------------------------------------------------------------
/src/animations/ParallaxScrollview.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | Animated,
5 | StyleSheet,
6 | ScrollView,
7 | Dimensions,
8 | Linking,
9 | } from 'react-native';
10 |
11 | import BackIcon from '../icons/BackIcon';
12 | import OpenIcon from '../icons/OpenIcon';
13 | import Moment from './components/moment';
14 |
15 | const { width, height } = Dimensions.get('window');
16 |
17 | const Images = [
18 | {
19 | title: 'Saling',
20 | image: require('./assets/images/1.jpeg'),
21 | }, {
22 | title: 'Lets Get It On',
23 | image: require('./assets/images/2.jpg'),
24 | }, {
25 | title: 'All Right',
26 | image: require('./assets/images/3.jpeg'),
27 | }, {
28 | title: 'Viva La Vida',
29 | image: require('./assets/images/4.jpeg'),
30 | },
31 | ];
32 |
33 | const getInterpolate = (animatedScroll, i, imageLength) => {
34 | const inputRange = [
35 | (i - 1) * width,
36 | i * width,
37 | (i + 1) * width,
38 | ];
39 |
40 | const outputRange = i === 0 ? [0, 0, 150] : [-300, 0, 150];
41 | return animatedScroll.interpolate({
42 | inputRange,
43 | outputRange,
44 | extrapolate: 'clamp',
45 | });
46 | };
47 |
48 | const getSeparator = (i) => ();
52 |
53 | class ParallaxScrollview extends Component {
54 | static navigationOptions = ({ navigation }) => ({
55 | headerTitle: 'Magic Card',
56 | headerStyle: {
57 | height: 80,
58 | backgroundColor: '#EC407A',
59 | justifyContent: 'center',
60 | },
61 | headerTitleStyle: {
62 | color: 'white',
63 | fontSize: 20,
64 | fontWeight: '400',
65 | },
66 | headerLeft: navigation.goBack()} />,
67 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/ParallaxScrollview.js')} />,
68 | })
69 |
70 | constructor(props) {
71 | super(props);
72 | this.state = {
73 | animatedScroll: new Animated.Value(0),
74 | scrollEnabled: true,
75 | };
76 | }
77 |
78 | handleFocus = (focused) => {
79 | this.setState({
80 | scrollEnabled: !focused,
81 | });
82 | }
83 |
84 | render() {
85 | return (
86 |
87 |
104 | {Images.map((image, i) => (
105 |
112 | ))}
113 | {Array(...{ length: Images.length + 1 }).map((_, i) => getSeparator(i))}
114 |
115 |
116 | );
117 | }
118 | }
119 |
120 | const styles = StyleSheet.create({
121 | container: {
122 | height,
123 | width,
124 | overflow: 'hidden',
125 | },
126 | separate: {
127 | backgroundColor: 'black',
128 | position: 'absolute',
129 | top: 0,
130 | bottom: 0,
131 | width: 5,
132 | },
133 | });
134 |
135 | export default ParallaxScrollview;
136 |
--------------------------------------------------------------------------------
/src/animations/SpringyMenu.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | StyleSheet,
5 | Linking,
6 | Animated,
7 | TouchableOpacity,
8 | Text,
9 | } from 'react-native';
10 |
11 | import BackIcon from '../icons/BackIcon';
12 | import OpenIcon from '../icons/OpenIcon';
13 |
14 | const getTransformStyle = (animation) => ({
15 | transform: [
16 | { translateY: animation },
17 | ],
18 | });
19 |
20 | class SpringyMenu extends Component {
21 | static navigationOptions = ({ navigation }) => ({
22 | headerTitle: 'Springy Menu',
23 | headerStyle: {
24 | height: 80,
25 | backgroundColor: '#EC407A',
26 | justifyContent: 'center',
27 | },
28 | headerTitleStyle: {
29 | color: 'white',
30 | fontSize: 20,
31 | fontWeight: '400',
32 | },
33 | headerLeft: navigation.goBack()} />,
34 | headerRight: Linking.openURL('https://github.com/bkdev98/react-native-animation-examples/blob/master/src/animations/SpringyMenu.js')} />,
35 | })
36 |
37 | constructor(props) {
38 | super(props);
39 | this.state = {
40 | animate: new Animated.Value(0),
41 | fabs: [
42 | new Animated.Value(0),
43 | new Animated.Value(0),
44 | new Animated.Value(0),
45 | ],
46 | };
47 | this.open = false;
48 | }
49 |
50 | handlePress = () => {
51 | const toValue = this.open ? 0 : 1;
52 | const flyouts = this.state.fabs.map((value, i) => Animated.spring(value, {
53 | toValue: (i + 1) * -90 * toValue,
54 | friction: 5,
55 | }));
56 |
57 | Animated.parallel([
58 | Animated.timing(this.state.animate, {
59 | toValue,
60 | duration: 300,
61 | }),
62 | Animated.stagger(30, flyouts),
63 | ]).start();
64 | this.open = !this.open;
65 | }
66 |
67 | render() {
68 | const backgroundInterpolate = this.state.animate.interpolate({
69 | inputRange: [0, 1],
70 | outputRange: ['rgb(90,34,153)', 'rgb(36,11,63)'],
71 | });
72 |
73 | const backgroundStyle = {
74 | backgroundColor: backgroundInterpolate,
75 | };
76 |
77 | const buttonColorInterpolate = this.state.animate.interpolate({
78 | inputRange: [0, 1],
79 | outputRange: ['rgb(24,214,255)', 'rgb(255,255,255)'],
80 | });
81 |
82 | const buttonRotate = this.state.animate.interpolate({
83 | inputRange: [0, 1],
84 | outputRange: ['0deg', '135deg'],
85 | });
86 |
87 | const buttonStyle = {
88 | backgroundColor: buttonColorInterpolate,
89 | transform: [
90 | { rotate: buttonRotate },
91 | ],
92 | };
93 |
94 | return (
95 |
96 |
97 |
98 | {
99 | this.state.fabs.map((animation, i) => (
100 |
105 | ))
106 | }
107 |
108 |
109 | +
110 |
111 |
112 |
113 |
114 |
115 | );
116 | }
117 | }
118 |
119 | const styles = StyleSheet.create({
120 | container: {
121 | flex: 1,
122 | justifyContent: 'center',
123 | alignItems: 'center',
124 | },
125 | menuContainer: {
126 | flex: 1,
127 | },
128 | position: {
129 | position: 'absolute',
130 | right: 45,
131 | bottom: 45,
132 | },
133 | fab: {
134 | position: 'absolute',
135 | bottom: 0,
136 | right: 0,
137 | },
138 | button: {
139 | width: 80,
140 | height: 80,
141 | borderRadius: 40,
142 | alignItems: 'center',
143 | justifyContent: 'center',
144 | },
145 | flyout: {
146 | backgroundColor: '#9439FF',
147 | },
148 | plus: {
149 | fontWeight: 'bold',
150 | fontSize: 30,
151 | color: '#00768F',
152 | },
153 | });
154 |
155 | export default SpringyMenu;
156 |
--------------------------------------------------------------------------------
/src/animations/assets/images/1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bkdev98/react-native-animation-examples/2ee8721f771cb4ab1872d5a29828d8bc916fb41d/src/animations/assets/images/1.jpeg
--------------------------------------------------------------------------------
/src/animations/assets/images/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bkdev98/react-native-animation-examples/2ee8721f771cb4ab1872d5a29828d8bc916fb41d/src/animations/assets/images/2.jpg
--------------------------------------------------------------------------------
/src/animations/assets/images/3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bkdev98/react-native-animation-examples/2ee8721f771cb4ab1872d5a29828d8bc916fb41d/src/animations/assets/images/3.jpeg
--------------------------------------------------------------------------------
/src/animations/assets/images/4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bkdev98/react-native-animation-examples/2ee8721f771cb4ab1872d5a29828d8bc916fb41d/src/animations/assets/images/4.jpeg
--------------------------------------------------------------------------------
/src/animations/assets/images/beansable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bkdev98/react-native-animation-examples/2ee8721f771cb4ab1872d5a29828d8bc916fb41d/src/animations/assets/images/beansable.png
--------------------------------------------------------------------------------
/src/animations/components/heart.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, StyleSheet, Animated } from 'react-native';
3 |
4 | const Heart = ({ filled, style, ...props }) => {
5 | const centerNonFilled = (
6 |
7 |
8 |
9 |
10 | );
11 | const fillStyle = filled ? styles.filledHeart : styles.empty;
12 | return (
13 |
14 |
15 |
16 | {!filled && centerNonFilled}
17 |
18 | );
19 | };
20 |
21 | const styles = StyleSheet.create({
22 | heart: {
23 | width: 50,
24 | height: 50,
25 | backgroundColor: 'transparent',
26 | },
27 | heartShape: {
28 | width: 30,
29 | height: 45,
30 | position: 'absolute',
31 | top: 0,
32 | borderTopLeftRadius: 15,
33 | borderTopRightRadius: 15,
34 | },
35 | filledHeart: {
36 | backgroundColor: '#EC407A',
37 | },
38 | fit: {
39 | transform: [
40 | { scale: 0.9 },
41 | ],
42 | },
43 | emptyFill: {
44 | backgroundColor: '#FFF',
45 | },
46 | empty: {
47 | backgroundColor: '#CCC',
48 | },
49 | leftHeart: {
50 | transform: [
51 | { rotate: '-45deg' },
52 | ],
53 | left: 5,
54 | },
55 | rightHeart: {
56 | transform: [
57 | { rotate: '45deg' },
58 | ],
59 | right: 5,
60 | },
61 | });
62 |
63 | export default Heart;
64 |
--------------------------------------------------------------------------------
/src/animations/components/moment.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Animated,
7 | Dimensions,
8 | TouchableWithoutFeedback,
9 | } from 'react-native';
10 |
11 | const { width, height } = Dimensions.get('window');
12 |
13 | class Moment extends Component {
14 | state = {
15 | scale: new Animated.Value(1),
16 | }
17 |
18 | componentWillMount() {
19 | this.bgFadeInterpolate = this.state.scale.interpolate({
20 | inputRange: [0.9, 1],
21 | outputRange: ['rgba(0,0,0,.3)', 'rgba(0,0,0,0)'],
22 | });
23 | this.textFade = this.state.scale.interpolate({
24 | inputRange: [0.9, 1],
25 | outputRange: [0, 1],
26 | });
27 | this.calloutTranslate = this.state.scale.interpolate({
28 | inputRange: [0.9, 1],
29 | outputRange: [0, 150],
30 | });
31 | }
32 |
33 | handlePress = () => {
34 | if (this.props.focused) {
35 | Animated.timing(this.state.scale, {
36 | toValue: 1,
37 | duration: 300,
38 | }).start(() => this.props.onFocus(false));
39 | return;
40 | }
41 | Animated.timing(this.state.scale, {
42 | toValue: 0.9,
43 | duration: 300,
44 | }).start(() => this.props.onFocus(true));
45 | }
46 |
47 | render() {
48 | const animatedStyle = {
49 | transform: [
50 | { translateX: this.props.translateX },
51 | { scale: this.state.scale },
52 | ],
53 | };
54 |
55 | const bgFadeStyle = {
56 | backgroundColor: this.bgFadeInterpolate,
57 | };
58 |
59 | const textFadeStyle = {
60 | opacity: this.textFade,
61 | };
62 |
63 | const calloutStyle = {
64 | transform: [{
65 | translateY: this.calloutTranslate,
66 | }],
67 | };
68 |
69 | return (
70 |
71 |
76 |
77 |
78 |
79 | {this.props.title}
80 |
81 |
82 |
83 |
84 |
85 | {this.props.title}
86 |
87 |
88 |
89 | );
90 | }
91 | }
92 |
93 | const styles = StyleSheet.create({
94 | container: {
95 | width,
96 | height,
97 | overflow: 'hidden',
98 | },
99 | image: {
100 | flex: 1,
101 | width: null,
102 | height: null,
103 | },
104 | center: {
105 | justifyContent: 'center',
106 | },
107 | textWrap: {
108 | backgroundColor: 'rgba(0,0,0,.5)',
109 | paddingVertical: 10,
110 | },
111 | title: {
112 | backgroundColor: 'transparent',
113 | fontSize: 30,
114 | color: 'white',
115 | textAlign: 'center',
116 | },
117 | callout: {
118 | height: 150,
119 | backgroundColor: 'rgba(0,0,0,.5)',
120 | position: 'absolute',
121 | bottom: 0,
122 | right: 0,
123 | left: 0,
124 | },
125 | });
126 |
127 | export default Moment;
128 |
--------------------------------------------------------------------------------
/src/components/Info.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | View,
4 | Text,
5 | TouchableOpacity,
6 | TouchableWithoutFeedback,
7 | Animated,
8 | StyleSheet,
9 | Linking,
10 | Dimensions,
11 | } from 'react-native';
12 |
13 | const { width, height } = Dimensions.get('window');
14 |
15 | class Info extends Component {
16 | componentWillMount() {
17 | this.animate = new Animated.Value(0);
18 | }
19 |
20 | render() {
21 | return (
22 |
23 | this.props.onPress()}>
24 |
25 |
26 |
27 |
28 |
29 |
30 | Animations Collection
31 |
32 |
33 | Created by Quoc Khanh
34 | & React Native 💖
35 |
36 | Linking.openURL('https://facebook.com/bkdev98')}
39 | >
40 | CONTACT
41 |
42 |
43 |
44 |
45 | );
46 | }
47 | }
48 |
49 | const styles = StyleSheet.create({
50 | container: {
51 | flex: 1,
52 | width,
53 | height: height * 0.8,
54 | alignItems: 'center',
55 | justifyContent: 'center',
56 | },
57 | infoContainer: {
58 | // flex: 1,
59 | width: width * 0.8,
60 | height: 250,
61 | },
62 | infoOverlay: {
63 | position: 'absolute',
64 | flex: 1,
65 | height,
66 | width,
67 | backgroundColor: 'rgba(0,0,0,.4)',
68 | },
69 | titleContainer: {
70 | flex: 4,
71 | backgroundColor: '#F06292',
72 | alignItems: 'center',
73 | justifyContent: 'center',
74 | },
75 | title: {
76 | fontSize: 24,
77 | color: 'white',
78 | },
79 | contentContainer: {
80 | flex: 3,
81 | backgroundColor: 'white',
82 | alignItems: 'center',
83 | justifyContent: 'space-around',
84 | paddingVertical: 10,
85 | },
86 | createdBy: {
87 | fontSize: 20,
88 | color: '#616161',
89 | },
90 | description: {
91 | fontSize: 20,
92 | color: '#F06292',
93 | },
94 | button: {
95 | flex: 3,
96 | backgroundColor: '#F8BBD0',
97 | alignItems: 'center',
98 | justifyContent: 'center',
99 | },
100 | buttonText: {
101 | color: '#EC407A',
102 | fontSize: 17,
103 | letterSpacing: 1.4,
104 | fontWeight: 'bold',
105 | },
106 | });
107 |
108 | export default Info;
109 |
--------------------------------------------------------------------------------
/src/components/List.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import {
3 | FlatList,
4 | Text,
5 | View,
6 | TouchableOpacity,
7 | StyleSheet,
8 | StatusBar,
9 | Share,
10 | } from 'react-native';
11 |
12 | import ShareIcon from '../icons/ShareIcon';
13 | import HelpIcon from '../icons/HelpIcon';
14 | import Info from './Info';
15 |
16 | const data = [{
17 | // key: 'AnimatedBasic',
18 | // title: 'Animated Basic',
19 | // }, {
20 | // key: 'MagicButton',
21 | // title: 'Magic Button',
22 | // }, {
23 | // key: 'MagicCard',
24 | // title: 'Magic Card',
25 | // }, {
26 | // key: 'ColorBox',
27 | // title: 'Color Box',
28 | // }, {
29 | key: 'ParallaxScrollview',
30 | title: 'Parallax Scrollview',
31 | icon: '🐬',
32 | }, {
33 | key: 'BouncingHeart',
34 | title: 'Bouncing Heart',
35 | icon: '💕',
36 | }, {
37 | key: 'SpringyMenu',
38 | title: 'Springy Menu',
39 | icon: '🍕',
40 | }, {
41 | key: 'CommentModal',
42 | title: 'Comment Modal',
43 | icon: '🍻',
44 | }, {
45 | key: 'FloatingHeart',
46 | title: 'Floating Heart',
47 | icon: '🦄',
48 | }, {
49 | key: 'EventCard',
50 | title: 'Event Card',
51 | icon: '🎼',
52 | }, {
53 | key: 'CollapseHeader',
54 | title: 'Collapse Header',
55 | icon: '🎃',
56 | }, {
57 | key: 'MagicInput',
58 | title: 'Magic Input',
59 | icon: '💅',
60 | }];
61 |
62 | class List extends Component {
63 | static navigationOptions = ({ navigation }) => ({
64 | headerTitle: 'Animations',
65 | headerStyle: {
66 | height: 80,
67 | backgroundColor: '#EC407A',
68 | justifyContent: 'center',
69 | },
70 | headerTitleStyle: {
71 | color: 'white',
72 | fontSize: 20,
73 | fontWeight: '400',
74 | },
75 | headerRight: Share.share({
76 | message: 'Well its not far down to paradise, at leasts not for me',
77 | title: 'Christopher Cross',
78 | url: 'https://github.com/bkdev98/react-native-animation-examples',
79 | }, {
80 | dialogTitle: 'Sailing',
81 | })}
82 | />,
83 | headerLeft: navigation.state.params ? navigation.state.params.headerLeft : null,
84 | })
85 |
86 | state = {
87 | infoOpen: false,
88 | }
89 |
90 | componentDidMount() {
91 | this.props.navigation.setParams({
92 | headerLeft: ,
93 | });
94 | }
95 |
96 | toggleInfoDialog = () => {
97 | this.setState({
98 | infoOpen: !this.state.infoOpen,
99 | });
100 | }
101 |
102 | render() {
103 | return (
104 |
105 | {this.state.infoOpen &&
106 |
107 | this.setState({ infoOpen: true })} />
108 |
109 | }
110 |
111 |
112 |
115 | ( this.props.navigation.navigate(item.key)}
117 | style={[styles.itemContainer, { backgroundColor: `rgba(255, 26, 117, ${0.3 + (0.05 * index)})` }]}
118 | >
119 |
120 | {item.icon}
121 |
122 |
123 | {item.title}
124 |
125 | )
126 | }
127 | />
128 |
129 | );
130 | }
131 | }
132 |
133 | const styles = StyleSheet.create({
134 | container: {
135 | flex: 1,
136 | },
137 | infoContainer: {
138 | position: 'absolute',
139 | zIndex: 1000,
140 | },
141 | headerContainer: {
142 | height: 100,
143 | backgroundColor: '#EC407A',
144 | justifyContent: 'center',
145 | alignItems: 'center',
146 | },
147 | headerTitle: {
148 | color: 'white',
149 | fontSize: 25,
150 | },
151 | itemContainer: {
152 | flexDirection: 'row',
153 | height: 90,
154 | },
155 | iconContainer: {
156 | width: 90,
157 | backgroundColor: 'rgba(255,255,255,.1)',
158 | justifyContent: 'center',
159 | alignItems: 'center',
160 | },
161 | icon: {
162 | fontSize: 30,
163 | },
164 | itemTitleContainer: {
165 | justifyContent: 'center',
166 | paddingLeft: 20,
167 | },
168 | itemTitle: {
169 | color: 'white',
170 | fontSize: 20,
171 | },
172 | });
173 |
174 | export default List;
175 |
--------------------------------------------------------------------------------
/src/components/StatusBar.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Platform, View } from 'react-native';
3 |
4 | const StatusBar = () => (
5 | Platform.OS === 'android' && Platform.Version >= 20 ?
6 |
7 | :
8 | );
9 |
10 | export default StatusBar;
11 |
--------------------------------------------------------------------------------
/src/icons/BackIcon.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableOpacity } from 'react-native';
3 | import Ionicons from '@expo/vector-icons/Ionicons';
4 |
5 | const BackIcon = ({ onPress }) => (
6 |
15 |
16 |
17 | );
18 |
19 | export default BackIcon;
20 |
--------------------------------------------------------------------------------
/src/icons/HelpIcon.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableOpacity } from 'react-native';
3 | import Ionicons from '@expo/vector-icons/Ionicons';
4 |
5 | const ShareIcon = ({ onPress }) => (
6 |
15 |
16 |
17 | );
18 |
19 | export default ShareIcon;
20 |
--------------------------------------------------------------------------------
/src/icons/MenuIcon.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableOpacity } from 'react-native';
3 | import Ionicons from '@expo/vector-icons/Ionicons';
4 |
5 | const ShareIcon = ({ onPress }) => (
6 |
15 |
16 |
17 | );
18 |
19 | export default ShareIcon;
20 |
--------------------------------------------------------------------------------
/src/icons/OpenIcon.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableOpacity } from 'react-native';
3 | import Ionicons from '@expo/vector-icons/Ionicons';
4 |
5 | const OpenIcon = ({ onPress }) => (
6 |
14 |
15 |
16 | );
17 |
18 | export default OpenIcon;
19 |
--------------------------------------------------------------------------------
/src/icons/ShareIcon.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableOpacity } from 'react-native';
3 | import Ionicons from '@expo/vector-icons/Ionicons';
4 |
5 | const ShareIcon = ({ onPress }) => (
6 |
14 |
15 |
16 | );
17 |
18 | export default ShareIcon;
19 |
--------------------------------------------------------------------------------