├── .gitignore
├── App.tsx
├── README.md
├── babel.config.js
├── package.json
├── src
├── Colors.ts
└── examples
│ ├── RadiusBackground
│ └── index.tsx
│ └── TabHeart
│ └── index.tsx
├── tsconfig.json
├── webpack.config.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 |
33 | # node.js
34 | #
35 | node_modules/
36 | npm-debug.log
37 | yarn-error.log
38 |
39 | # BUCK
40 | buck-out/
41 | \.buckd/
42 | *.keystore
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | */fastlane/report.xml
52 | */fastlane/Preview.html
53 | */fastlane/screenshots
54 |
55 | # Bundle artifacts
56 | *.jsbundle
57 |
58 | # CocoaPods
59 | /ios/Pods/
60 |
61 | # Expo
62 | .expo/*
63 | web-build/
--------------------------------------------------------------------------------
/App.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Pressable, StyleSheet, Text, View } from 'react-native';
3 | import { NavigationContainer, useNavigation } from '@react-navigation/native';
4 | import { createStackNavigator } from '@react-navigation/stack';
5 | import { SafeAreaView } from 'react-native-safe-area-context';
6 | import { ScrollView } from 'react-native-gesture-handler';
7 |
8 | import Colors from './src/Colors';
9 |
10 | import RadiusBackground from './src/examples/RadiusBackground';
11 | import TabHeart from './src/examples/TabHeart';
12 |
13 | const Stack = createStackNavigator();
14 |
15 | function HomeScreen() {
16 | const navigation = useNavigation();
17 |
18 | return (
19 |
20 |
21 | navigation.navigate('RadiusBackground')}
23 | style={styles.screenContianer}
24 | >
25 |
26 | Radius background
27 |
28 |
29 | navigation.navigate('TabHeart')}
31 | style={styles.screenContianer}
32 | >
33 |
34 | TabHeart
35 |
36 |
37 |
38 |
39 | );
40 | }
41 |
42 | export default function App() {
43 | return (
44 |
45 |
46 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | );
58 | }
59 |
60 | const styles = StyleSheet.create({
61 | contianer: {
62 | flex: 1,
63 | backgroundColor: Colors.black,
64 | paddingHorizontal: 10,
65 | paddingTop: 10,
66 | },
67 | screenContianer: {
68 | paddingVertical: 16,
69 | paddingHorizontal: 12,
70 | backgroundColor: Colors.white,
71 | borderRadius: 8,
72 | marginVertical: 10,
73 | },
74 | screenTitle: {
75 | fontSize: 28,
76 | fontWeight: 'bold',
77 | color: '#17202A',
78 | },
79 | });
80 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Native Animation Examples
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ## 🚀 How to use
19 |
20 | > `yarn install `
21 |
22 | - If you want to run in ios device `yarn ios`.
23 | - If you want to run in android device `yarn android`.
24 |
25 | # Purpose
26 |
27 | ### This library purpose is to share a diferents examples of comon uses cases of animations some of the there more easy and other more complex
28 |
29 | - The examples use Reanimated in version 2 and Moti:
30 | - [Reanimated](https://docs.expo.io/versions/latest/sdk/reanimated)
31 | - [Moti](https://moti.fyi/)
32 |
33 | > 🧠 Feel free to open a PR to add more axamples
34 |
35 | # Examples
36 |
37 | [Radius background](https://github.com/rokkoo/react-native-animation-examples/blob/main/src/examples/RadiusBackground/index.tsx)
38 |
39 | 
40 |
41 | [Tab Heart](https://github.com/rokkoo/react-native-animation-examples/tree/main/src/examples/TabHeart/index.tsx)
42 |
43 | 
44 |
45 | ## 📝 Docs
46 |
47 | - [Expo Reanimated docs](https://docs.expo.io/versions/latest/sdk/reanimated)
48 | - [Moti docs](https://moti.fyi/)
49 | - [Reanimated docs](https://docs.swmansion.com/react-native-reanimated/docs/2.0.0-alpha.8/)
50 |
51 | # Persons
52 |
53 | - Follor creator of Moti [Fernando Rojo](https://twitter.com/FernandoTheRojo) for updates.
54 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | plugins: ['react-native-reanimated/plugin']
6 | };
7 | };
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": {
3 | "name": "Alfonso Lasa",
4 | "url": "https://twitter.com/alfonso_dev"
5 | },
6 | "description": "A repository with some examples with Reanimated and Moti library",
7 | "version": "0.0.1",
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/rokkoo/react-native-animation-examples"
11 | },
12 | "license": "MIT",
13 | "dependencies": {
14 | "@react-native-community/masked-view": "0.1.10",
15 | "@react-navigation/native": "^5.9.3",
16 | "@react-navigation/stack": "^5.14.3",
17 | "expo": "~40.0.0",
18 | "framer-motion": "^3.3.0",
19 | "moti": "^0.4.1",
20 | "react": "16.13.1",
21 | "react-dom": "16.13.1",
22 | "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
23 | "react-native-gesture-handler": "~1.8.0",
24 | "react-native-reanimated": "2.0.0-rc.0",
25 | "react-native-safe-area-context": "3.1.9",
26 | "react-native-screens": "~2.15.2",
27 | "react-native-web": "~0.13.12"
28 | },
29 | "devDependencies": {
30 | "@babel/core": "~7.9.0",
31 | "@expo/webpack-config": "^0.12.58",
32 | "@types/react": "~16.9.35",
33 | "@types/react-native": "~0.63.2",
34 | "typescript": "~4.0.0"
35 | },
36 | "scripts": {
37 | "start": "expo start",
38 | "android": "expo start --android",
39 | "ios": "expo start --ios",
40 | "web": "expo start --web",
41 | "eject": "expo eject"
42 | },
43 | "private": false
44 | }
45 |
--------------------------------------------------------------------------------
/src/Colors.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | orange: 'rgb(255, 87, 51)',
3 | yellow: 'rgb(224, 255, 51)',
4 | green: 'rgb(119, 255, 51)',
5 | blue: 'rgb(51, 54, 255)',
6 | pink: 'rgb(233, 51, 255)',
7 | black: 'rgb(33, 47, 60)',
8 | white: 'rgb(247, 249, 249)',
9 | red: 'rgb(231, 76, 60)'
10 | }
--------------------------------------------------------------------------------
/src/examples/RadiusBackground/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useReducer, useState } from 'react';
2 | import { Pressable, StyleSheet } from 'react-native';
3 | import { View, AnimatePresence, SafeAreaView } from 'moti';
4 |
5 | import Colors from '../../Colors';
6 |
7 | const AimatedBackground = ({ bg }) => {
8 | return (
9 |
33 | );
34 | };
35 |
36 | export default function RadiousBackground() {
37 | const [selectedColor, setSelectedColor] = useState(Colors.orange);
38 | const [backgroundColor, setBackgroundColor] = useState(selectedColor);
39 | const [visible, toggle] = useReducer((s) => !s, true);
40 |
41 | const ColorView = ({ color }) => {
42 | return (
43 | {
45 | setSelectedColor((prevColor) => {
46 | setBackgroundColor(prevColor);
47 | return color;
48 | });
49 |
50 | if (visible) {
51 | setTimeout(() => {
52 | toggle();
53 | }, 0);
54 | }
55 |
56 | toggle();
57 | }}
58 | >
59 |
60 |
61 | );
62 | };
63 |
64 | return (
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | {visible && }
76 |
77 |
78 | );
79 | }
80 |
81 | const styles = StyleSheet.create({
82 | container: {
83 | flex: 1,
84 | justifyContent: 'center',
85 | },
86 | bg: {
87 | position: 'absolute',
88 | borderRadius: 50,
89 | right: 0,
90 | },
91 | colorsContianer: {
92 | zIndex: 10,
93 | marginTop: 20,
94 | flexDirection: 'row',
95 | justifyContent: 'center',
96 | },
97 | colorContainer: {
98 | width: 50,
99 | height: 50,
100 | borderRadius: 40,
101 | borderColor: 'white',
102 | borderWidth: 4,
103 | marginHorizontal: 8,
104 | },
105 | });
106 |
--------------------------------------------------------------------------------
/src/examples/TabHeart/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useReducer } from 'react';
2 | import { StyleSheet, Pressable, View } from 'react-native';
3 | import { View as MotiView, AnimatePresence, Text as MotiText } from 'moti';
4 | import { AntDesign } from '@expo/vector-icons';
5 |
6 | import Colors from '../../Colors';
7 |
8 | const TabHeart = () => {
9 | const [like, toggleLike] = useReducer((l) => !l, false);
10 |
11 | return (
12 |
13 |
14 |
15 |
16 |
24 |
38 |
43 |
44 |
45 |
46 |
47 |
52 | {like ? 'Like' : 'Dislike'}
53 |
54 | )
55 |
56 |
57 |
58 |
59 | );
60 | };
61 |
62 | const styles = StyleSheet.create({
63 | container: {
64 | alignItems: 'center',
65 | justifyContent: 'center',
66 | backgroundColor: Colors.black,
67 | flex: 1,
68 | },
69 | animationContianer: {
70 | backgroundColor: '#283747',
71 | flexDirection: 'row',
72 | justifyContent: 'center',
73 | alignItems: 'center',
74 | paddingVertical: 18,
75 | paddingHorizontal: 40,
76 | borderRadius: 30,
77 | },
78 | text: {
79 | color: Colors.white,
80 | fontSize: 24,
81 | marginLeft: 14,
82 | },
83 | });
84 |
85 | export default TabHeart;
86 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "jsx": "react-native",
4 | "target": "esnext",
5 | "lib": [
6 | "esnext"
7 | ],
8 | "allowJs": true,
9 | "skipLibCheck": true,
10 | "noEmit": true,
11 | "allowSyntheticDefaultImports": true,
12 | "resolveJsonModule": true,
13 | "esModuleInterop": true,
14 | "moduleResolution": "node"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const createExpoWebpackConfigAsync = require('@expo/webpack-config')
2 |
3 | module.exports = async function (env, argv) {
4 | const config = await createExpoWebpackConfigAsync(
5 | {
6 | ...env,
7 | babel: { dangerouslyAddModulePathsToTranspile: ['moti'] },
8 | },
9 | argv
10 | )
11 |
12 | return config
13 | }
--------------------------------------------------------------------------------