├── .gitignore ├── 01-animated-login-screen ├── Part 1 │ ├── .gitignore │ ├── App.js │ ├── app.json │ ├── app │ │ └── index.js │ ├── assets │ │ ├── bg.jpg │ │ ├── icon.png │ │ └── splash.png │ ├── babel.config.js │ ├── package.json │ └── yarn.lock └── Part 2 │ ├── .gitignore │ ├── App.js │ ├── app.json │ ├── app │ └── index.js │ ├── assets │ ├── bg.jpg │ ├── icon.png │ └── splash.png │ ├── babel.config.js │ ├── package.json │ └── yarn.lock ├── 02-uber-login-screen ├── part-2 │ ├── App.js │ ├── Constants.js │ ├── app.json │ ├── assets │ │ ├── icon.png │ │ └── splash.png │ ├── babel.config.js │ ├── components │ │ └── Logo.js │ ├── package.json │ └── yarn.lock ├── part-3 │ ├── App.js │ ├── Constants.js │ ├── app.json │ ├── assets │ │ ├── icon.png │ │ ├── india.png │ │ └── splash.png │ ├── babel.config.js │ ├── components │ │ └── Logo.js │ ├── package.json │ └── yarn.lock ├── part-4 │ ├── App.js │ ├── Constants.js │ ├── app.json │ ├── assets │ │ ├── icon.png │ │ ├── india.png │ │ └── splash.png │ ├── babel.config.js │ ├── components │ │ ├── Logo.js │ │ └── OverlayBg.js │ ├── package.json │ └── yarn.lock └── part-5 │ ├── App.js │ ├── Constants.js │ ├── app.json │ ├── assets │ ├── icon.png │ ├── india.png │ └── splash.png │ ├── components │ ├── AnimatedPlaceholder.js │ ├── HeaderBackArrow.js │ ├── Logo.js │ └── OverlayBg.js │ ├── package.json │ └── yarn.lock └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | *.jks 5 | *.p8 6 | *.p12 7 | *.key 8 | *.mobileprovision 9 | *.orig.* 10 | web-build/ 11 | web-report/ 12 | -------------------------------------------------------------------------------- /01-animated-login-screen/Part 1/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | *.jks 5 | *.p8 6 | *.p12 7 | *.key 8 | *.mobileprovision 9 | *.orig.* 10 | web-build/ 11 | web-report/ 12 | -------------------------------------------------------------------------------- /01-animated-login-screen/Part 1/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, Text, View } from 'react-native'; 3 | 4 | import { Asset } from 'expo-asset'; 5 | import { AppLoading } from 'expo'; 6 | import MusicApp from './app/index'; 7 | function cacheImages(images) { 8 | return images.map(image => { 9 | if (typeof image === 'string') { 10 | return Image.prefetch(image); 11 | } else { 12 | return Asset.fromModule(image).downloadAsync(); 13 | } 14 | }); 15 | } 16 | export default class App extends React.Component { 17 | constructor() { 18 | super(); 19 | this.state = { 20 | isReady: false 21 | }; 22 | } 23 | 24 | async _loadAssetsAsync() { 25 | const imageAssets = cacheImages([require('./assets/bg.jpg')]); 26 | 27 | await Promise.all([...imageAssets]); 28 | } 29 | 30 | render() { 31 | if (!this.state.isReady) { 32 | return ( 33 | this.setState({ isReady: true })} 36 | onError={console.warn} 37 | /> 38 | ); 39 | } 40 | return ; 41 | } 42 | } 43 | const styles = StyleSheet.create({ 44 | container: { 45 | flex: 1, 46 | backgroundColor: '#fff', 47 | alignItems: 'center', 48 | justifyContent: 'center' 49 | } 50 | }); 51 | -------------------------------------------------------------------------------- /01-animated-login-screen/Part 1/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "foccy music app", 4 | "slug": "foccy-music-app-youtube-complete", 5 | "privacy": "public", 6 | "sdkVersion": "34.0.0", 7 | "platforms": [ 8 | "ios", 9 | "android", 10 | "web" 11 | ], 12 | "version": "1.0.0", 13 | "orientation": "portrait", 14 | "icon": "./assets/icon.png", 15 | "splash": { 16 | "image": "./assets/splash.png", 17 | "resizeMode": "contain", 18 | "backgroundColor": "#ffffff" 19 | }, 20 | "updates": { 21 | "fallbackToCacheTimeout": 0 22 | }, 23 | "assetBundlePatterns": [ 24 | "**/*" 25 | ], 26 | "ios": { 27 | "supportsTablet": true 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /01-animated-login-screen/Part 1/app/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { View, Text, StyleSheet, Image, Dimensions } from 'react-native'; 3 | 4 | const { width, height } = Dimensions.get('window'); 5 | class MusicApp extends Component { 6 | render() { 7 | return ( 8 | 15 | 16 | 20 | 21 | 22 | 23 | SIGN IN 24 | 25 | 26 | 27 | SIGN IN WITH FACEBOOK 28 | 29 | 30 | 31 | 32 | ); 33 | } 34 | } 35 | export default MusicApp; 36 | 37 | const styles = StyleSheet.create({ 38 | container: { 39 | flex: 1, 40 | alignItems: 'center', 41 | justifyContent: 'center' 42 | }, 43 | button: { 44 | backgroundColor: 'white', 45 | height: 70, 46 | marginHorizontal: 20, 47 | borderRadius: 35, 48 | alignItems: 'center', 49 | justifyContent: 'center', 50 | marginVertical: 5 51 | } 52 | }); 53 | -------------------------------------------------------------------------------- /01-animated-login-screen/Part 1/assets/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/01-animated-login-screen/Part 1/assets/bg.jpg -------------------------------------------------------------------------------- /01-animated-login-screen/Part 1/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/01-animated-login-screen/Part 1/assets/icon.png -------------------------------------------------------------------------------- /01-animated-login-screen/Part 1/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/01-animated-login-screen/Part 1/assets/splash.png -------------------------------------------------------------------------------- /01-animated-login-screen/Part 1/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /01-animated-login-screen/Part 1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "web": "expo start --web", 8 | "eject": "expo eject" 9 | }, 10 | "dependencies": { 11 | "expo": "^34.0.1", 12 | "expo-asset": "~6.0.0", 13 | "react": "16.8.3", 14 | "react-dom": "^16.8.6", 15 | "react-native": "https://github.com/expo/react-native/archive/sdk-34.0.0.tar.gz", 16 | "react-native-web": "^0.11.4" 17 | }, 18 | "devDependencies": { 19 | "babel-preset-expo": "^6.0.0" 20 | }, 21 | "private": true 22 | } 23 | -------------------------------------------------------------------------------- /01-animated-login-screen/Part 2/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | *.jks 5 | *.p8 6 | *.p12 7 | *.key 8 | *.mobileprovision 9 | *.orig.* 10 | web-build/ 11 | web-report/ 12 | -------------------------------------------------------------------------------- /01-animated-login-screen/Part 2/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, Text, View } from 'react-native'; 3 | 4 | import { Asset } from 'expo-asset'; 5 | import { AppLoading } from 'expo'; 6 | import MusicApp from './app/index'; 7 | function cacheImages(images) { 8 | return images.map(image => { 9 | if (typeof image === 'string') { 10 | return Image.prefetch(image); 11 | } else { 12 | return Asset.fromModule(image).downloadAsync(); 13 | } 14 | }); 15 | } 16 | export default class App extends React.Component { 17 | constructor() { 18 | super(); 19 | this.state = { 20 | isReady: false 21 | }; 22 | } 23 | 24 | async _loadAssetsAsync() { 25 | const imageAssets = cacheImages([require('./assets/bg.jpg')]); 26 | 27 | await Promise.all([...imageAssets]); 28 | } 29 | 30 | render() { 31 | if (!this.state.isReady) { 32 | return ( 33 | this.setState({ isReady: true })} 36 | onError={console.warn} 37 | /> 38 | ); 39 | } 40 | return ; 41 | } 42 | } 43 | const styles = StyleSheet.create({ 44 | container: { 45 | flex: 1, 46 | backgroundColor: '#fff', 47 | alignItems: 'center', 48 | justifyContent: 'center' 49 | } 50 | }); 51 | -------------------------------------------------------------------------------- /01-animated-login-screen/Part 2/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "foccy music app", 4 | "slug": "foccy-music-app-youtube-complete", 5 | "privacy": "public", 6 | "sdkVersion": "34.0.0", 7 | "platforms": [ 8 | "ios", 9 | "android", 10 | "web" 11 | ], 12 | "version": "1.0.0", 13 | "orientation": "portrait", 14 | "icon": "./assets/icon.png", 15 | "splash": { 16 | "image": "./assets/splash.png", 17 | "resizeMode": "contain", 18 | "backgroundColor": "#ffffff" 19 | }, 20 | "updates": { 21 | "fallbackToCacheTimeout": 0 22 | }, 23 | "assetBundlePatterns": [ 24 | "**/*" 25 | ], 26 | "ios": { 27 | "supportsTablet": true 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /01-animated-login-screen/Part 2/app/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { View, Text, StyleSheet, Image, Dimensions } from 'react-native'; 3 | 4 | import Animated, { Easing } from 'react-native-reanimated'; 5 | import { TapGestureHandler, State } from 'react-native-gesture-handler'; 6 | const { width, height } = Dimensions.get('window'); 7 | 8 | const { 9 | Value, 10 | event, 11 | block, 12 | cond, 13 | eq, 14 | set, 15 | Clock, 16 | startClock, 17 | stopClock, 18 | debug, 19 | timing, 20 | clockRunning, 21 | interpolate, 22 | Extrapolate 23 | } = Animated; 24 | 25 | function runTiming(clock, value, dest) { 26 | const state = { 27 | finished: new Value(0), 28 | position: new Value(0), 29 | time: new Value(0), 30 | frameTime: new Value(0) 31 | }; 32 | 33 | const config = { 34 | duration: 1000, 35 | toValue: new Value(0), 36 | easing: Easing.inOut(Easing.ease) 37 | }; 38 | 39 | return block([ 40 | cond(clockRunning(clock), 0, [ 41 | set(state.finished, 0), 42 | set(state.time, 0), 43 | set(state.position, value), 44 | set(state.frameTime, 0), 45 | set(config.toValue, dest), 46 | startClock(clock) 47 | ]), 48 | timing(clock, state, config), 49 | cond(state.finished, debug('stop clock', stopClock(clock))), 50 | state.position 51 | ]); 52 | } 53 | class MusicApp extends Component { 54 | constructor() { 55 | super(); 56 | 57 | this.buttonOpacity = new Value(1); 58 | 59 | this.onStateChange = event([ 60 | { 61 | nativeEvent: ({ state }) => 62 | block([ 63 | cond( 64 | eq(state, State.END), 65 | set(this.buttonOpacity, runTiming(new Clock(), 1, 0)) 66 | ) 67 | ]) 68 | } 69 | ]); 70 | 71 | this.buttonY = interpolate(this.buttonOpacity, { 72 | inputRange: [0, 1], 73 | outputRange: [100, 0], 74 | extrapolate: Extrapolate.CLAMP 75 | }); 76 | 77 | this.bgY = interpolate(this.buttonOpacity, { 78 | inputRange: [0, 1], 79 | outputRange: [-height / 3, 0], 80 | extrapolate: Extrapolate.CLAMP 81 | }); 82 | } 83 | render() { 84 | return ( 85 | 92 | 98 | 102 | 103 | 104 | 105 | 112 | SIGN IN 113 | 114 | 115 | 123 | 124 | SIGN IN WITH FACEBOOK 125 | 126 | 127 | 128 | 129 | ); 130 | } 131 | } 132 | export default MusicApp; 133 | 134 | const styles = StyleSheet.create({ 135 | container: { 136 | flex: 1, 137 | alignItems: 'center', 138 | justifyContent: 'center' 139 | }, 140 | button: { 141 | backgroundColor: 'white', 142 | height: 70, 143 | marginHorizontal: 20, 144 | borderRadius: 35, 145 | alignItems: 'center', 146 | justifyContent: 'center', 147 | marginVertical: 5 148 | } 149 | }); 150 | -------------------------------------------------------------------------------- /01-animated-login-screen/Part 2/assets/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/01-animated-login-screen/Part 2/assets/bg.jpg -------------------------------------------------------------------------------- /01-animated-login-screen/Part 2/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/01-animated-login-screen/Part 2/assets/icon.png -------------------------------------------------------------------------------- /01-animated-login-screen/Part 2/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/01-animated-login-screen/Part 2/assets/splash.png -------------------------------------------------------------------------------- /01-animated-login-screen/Part 2/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /01-animated-login-screen/Part 2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "web": "expo start --web", 8 | "eject": "expo eject" 9 | }, 10 | "dependencies": { 11 | "expo": "^34.0.1", 12 | "expo-asset": "~6.0.0", 13 | "react": "16.8.3", 14 | "react-dom": "^16.8.6", 15 | "react-native": "https://github.com/expo/react-native/archive/sdk-34.0.0.tar.gz", 16 | "react-native-gesture-handler": "1.3.0", 17 | "react-native-reanimated": "~1.1.0", 18 | "react-native-web": "^0.11.4" 19 | }, 20 | "devDependencies": { 21 | "babel-preset-expo": "^6.0.0" 22 | }, 23 | "private": true 24 | } 25 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-2/App.js: -------------------------------------------------------------------------------- 1 | import React, { useRef } from "react"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | import Logo from "./components/Logo"; 4 | import Animated, { 5 | useCode, 6 | cond, 7 | eq, 8 | set, 9 | interpolate, 10 | } from "react-native-reanimated"; 11 | import { withTimingTransition } from "react-native-redash"; 12 | import { SCREEN_HEIGHT, LOGIN_VIEW_HEIGHT } from "./Constants"; 13 | export default function App() { 14 | const scale = useRef(new Animated.Value(0)); 15 | const scaleAnimation = withTimingTransition(scale.current); 16 | 17 | // const translateY = interpolate(scaleAnimation, { 18 | // inputRange: [0, 1], 19 | // outputRange: [SCREEN_HEIGHT, SCREEN_HEIGHT - LOGIN_VIEW_HEIGHT], 20 | // }); 21 | 22 | const innerLoginY = interpolate(scaleAnimation, { 23 | inputRange: [0, 1], 24 | outputRange: [LOGIN_VIEW_HEIGHT, 0], 25 | }); 26 | 27 | useCode(() => cond(eq(scale.current, 0), set(scale.current, 1)), []); 28 | 29 | return ( 30 | 31 | 32 | 33 | 34 | 41 | 54 | Overlay Bg 55 | 56 | 57 | 67 | Login View 68 | 69 | 70 | 71 | 72 | ); 73 | } 74 | 75 | const styles = StyleSheet.create({ 76 | container: { 77 | flex: 1, 78 | backgroundColor: "#2289d6", 79 | }, 80 | logoContainer: { 81 | flex: 1, 82 | alignItems: "center", 83 | justifyContent: "center", 84 | }, 85 | }); 86 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-2/Constants.js: -------------------------------------------------------------------------------- 1 | import { Dimensions } from "react-native"; 2 | 3 | const { width, height } = Dimensions.get("window"); 4 | 5 | export const SCREEN_HEIGHT = height; 6 | export const SCREEN_WIDTH = width; 7 | 8 | export const TEXT_INPUT_HEIGHT = 150; 9 | export const FOOTER_HEIGHT = 70; 10 | 11 | export const LOGIN_VIEW_HEIGHT = TEXT_INPUT_HEIGHT + FOOTER_HEIGHT; 12 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-2/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "HelloWorld", 4 | "slug": "react-native-uber-ui", 5 | "platforms": [ 6 | "ios", 7 | "android", 8 | "web" 9 | ], 10 | "version": "1.0.0", 11 | "orientation": "portrait", 12 | "icon": "./assets/icon.png", 13 | "splash": { 14 | "image": "./assets/splash.png", 15 | "resizeMode": "contain", 16 | "backgroundColor": "#ffffff" 17 | }, 18 | "updates": { 19 | "fallbackToCacheTimeout": 0 20 | }, 21 | "assetBundlePatterns": [ 22 | "**/*" 23 | ], 24 | "ios": { 25 | "supportsTablet": true 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-2/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-2/assets/icon.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-2/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-2/assets/splash.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-2/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-2/components/Logo.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Animated from "react-native-reanimated"; 3 | import { View, Text, StyleSheet } from "react-native"; 4 | 5 | const Logo = ({ scale }) => ( 6 | 7 | Uber 8 | 9 | ); 10 | export default Logo; 11 | 12 | const styles = StyleSheet.create({ 13 | logo: { 14 | backgroundColor: "white", 15 | height: 120, 16 | width: 120, 17 | padding: 10, 18 | alignItems: "center", 19 | justifyContent: "center", 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "web": "expo start --web", 8 | "eject": "expo eject" 9 | }, 10 | "dependencies": { 11 | "expo": "~37.0.3", 12 | "react": "~16.9.0", 13 | "react-dom": "~16.9.0", 14 | "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz", 15 | "react-native-gesture-handler": "^1.6.1", 16 | "react-native-reanimated": "^1.8.0", 17 | "react-native-redash": "^12.6.1", 18 | "react-native-web": "~0.11.7" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.8.6", 22 | "babel-preset-expo": "~8.1.0", 23 | "eslint-config-react-native-up": "^1.0.7", 24 | "eslint-plugin-react-hooks": "^3.0.0" 25 | }, 26 | "private": true 27 | } 28 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-3/App.js: -------------------------------------------------------------------------------- 1 | import React, { useRef } from "react"; 2 | import { StyleSheet, Text, View, Image } from "react-native"; 3 | import Logo from "./components/Logo"; 4 | import Animated, { 5 | useCode, 6 | cond, 7 | eq, 8 | set, 9 | interpolate, 10 | } from "react-native-reanimated"; 11 | import { 12 | withTimingTransition, 13 | onGestureEvent, 14 | withSpringTransition, 15 | } from "react-native-redash"; 16 | import { SCREEN_HEIGHT, LOGIN_VIEW_HEIGHT } from "./Constants"; 17 | import { 18 | TextInput, 19 | TapGestureHandler, 20 | State, 21 | } from "react-native-gesture-handler"; 22 | export default function App() { 23 | const scale = useRef(new Animated.Value(0)); 24 | const scaleAnimation = withTimingTransition(scale.current); 25 | 26 | const innerLoginY = interpolate(scaleAnimation, { 27 | inputRange: [0, 1], 28 | outputRange: [LOGIN_VIEW_HEIGHT, 0], 29 | }); 30 | 31 | const gestureState = useRef(new Animated.Value(State.UNDETERMINED)); 32 | const gestureHandler = onGestureEvent({ state: gestureState.current }); 33 | 34 | const isOpen = useRef(new Animated.Value(0)); 35 | const isOpenAnimation = withSpringTransition(isOpen.current); 36 | 37 | const outerLoginY = interpolate(isOpenAnimation, { 38 | inputRange: [0, 1], 39 | outputRange: [SCREEN_HEIGHT - LOGIN_VIEW_HEIGHT, 0], 40 | }); 41 | 42 | useCode(() => 43 | cond(eq(gestureState.current, State.END), [ 44 | cond(eq(isOpen.current, 0), set(isOpen.current, 1)), 45 | ]), 46 | ); 47 | useCode(() => cond(eq(scale.current, 0), set(scale.current, 1)), []); 48 | 49 | return ( 50 | 51 | 52 | 53 | 54 | 61 | 74 | Overlay Bg 75 | 76 | 77 | 86 | 87 | Get moving with Uber 88 | 89 | 90 | 91 | 92 | 96 | 100 | +91 101 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | ); 114 | } 115 | 116 | const styles = StyleSheet.create({ 117 | container: { 118 | flex: 1, 119 | backgroundColor: "#2289d6", 120 | }, 121 | logoContainer: { 122 | flex: 1, 123 | alignItems: "center", 124 | justifyContent: "center", 125 | }, 126 | heading: { 127 | alignItems: "flex-start", 128 | marginHorizontal: 25, 129 | marginTop: 50, 130 | }, 131 | image: { 132 | height: 24, 133 | width: 24, 134 | resizeMode: "contain", 135 | }, 136 | prefix: { 137 | fontSize: 20, 138 | paddingHorizontal: 10, 139 | }, 140 | textInput: { 141 | flex: 1, 142 | fontSize: 20, 143 | }, 144 | textInputContainer: { 145 | flexDirection: "row", 146 | margin: 25, 147 | }, 148 | }); 149 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-3/Constants.js: -------------------------------------------------------------------------------- 1 | import { Dimensions } from "react-native"; 2 | 3 | const { width, height } = Dimensions.get("window"); 4 | 5 | export const SCREEN_HEIGHT = height; 6 | export const SCREEN_WIDTH = width; 7 | 8 | export const TEXT_INPUT_HEIGHT = 150; 9 | export const FOOTER_HEIGHT = 70; 10 | 11 | export const LOGIN_VIEW_HEIGHT = TEXT_INPUT_HEIGHT + FOOTER_HEIGHT; 12 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-3/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "HelloWorld", 4 | "slug": "react-native-uber-ui", 5 | "platforms": [ 6 | "ios", 7 | "android", 8 | "web" 9 | ], 10 | "version": "1.0.0", 11 | "orientation": "portrait", 12 | "icon": "./assets/icon.png", 13 | "splash": { 14 | "image": "./assets/splash.png", 15 | "resizeMode": "contain", 16 | "backgroundColor": "#ffffff" 17 | }, 18 | "updates": { 19 | "fallbackToCacheTimeout": 0 20 | }, 21 | "assetBundlePatterns": [ 22 | "**/*" 23 | ], 24 | "ios": { 25 | "supportsTablet": true 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-3/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-3/assets/icon.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-3/assets/india.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-3/assets/india.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-3/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-3/assets/splash.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-3/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-3/components/Logo.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Animated from "react-native-reanimated"; 3 | import { View, Text, StyleSheet } from "react-native"; 4 | 5 | const Logo = ({ scale }) => ( 6 | 7 | Uber 8 | 9 | ); 10 | export default Logo; 11 | 12 | const styles = StyleSheet.create({ 13 | logo: { 14 | backgroundColor: "white", 15 | height: 120, 16 | width: 120, 17 | padding: 10, 18 | alignItems: "center", 19 | justifyContent: "center", 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "web": "expo start --web", 8 | "eject": "expo eject" 9 | }, 10 | "dependencies": { 11 | "expo": "~37.0.3", 12 | "react": "~16.9.0", 13 | "react-dom": "~16.9.0", 14 | "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz", 15 | "react-native-gesture-handler": "^1.6.1", 16 | "react-native-reanimated": "^1.8.0", 17 | "react-native-redash": "^12.6.1", 18 | "react-native-web": "~0.11.7" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.8.6", 22 | "babel-preset-expo": "~8.1.0", 23 | "eslint-config-react-native-up": "^1.0.7", 24 | "eslint-plugin-react-hooks": "^3.0.0" 25 | }, 26 | "private": true 27 | } 28 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-4/App.js: -------------------------------------------------------------------------------- 1 | import React, { useRef } from "react"; 2 | import { StyleSheet, Text, View, Image } from "react-native"; 3 | import Logo from "./components/Logo"; 4 | import Animated, { 5 | useCode, 6 | cond, 7 | eq, 8 | set, 9 | interpolate, 10 | SpringUtils, 11 | } from "react-native-reanimated"; 12 | import { 13 | withTimingTransition, 14 | onGestureEvent, 15 | withSpringTransition, 16 | } from "react-native-redash"; 17 | import { SCREEN_HEIGHT, LOGIN_VIEW_HEIGHT } from "./Constants"; 18 | import { 19 | TextInput, 20 | TapGestureHandler, 21 | State, 22 | } from "react-native-gesture-handler"; 23 | import OverlayBg from "./components/OverlayBg"; 24 | export default function App() { 25 | const scale = useRef(new Animated.Value(0)); 26 | const scaleAnimation = withTimingTransition(scale.current); 27 | 28 | const innerLoginY = interpolate(scaleAnimation, { 29 | inputRange: [0, 1], 30 | outputRange: [LOGIN_VIEW_HEIGHT, 0], 31 | }); 32 | 33 | const gestureState = useRef(new Animated.Value(State.UNDETERMINED)); 34 | const gestureHandler = onGestureEvent({ state: gestureState.current }); 35 | 36 | const isOpen = useRef(new Animated.Value(0)); 37 | const isOpenAnimation = withSpringTransition(isOpen.current, { 38 | ...SpringUtils.makeDefaultConfig(), 39 | overshootClamping: true, 40 | damping: new Animated.Value(20), 41 | }); 42 | 43 | const outerLoginY = interpolate(isOpenAnimation, { 44 | inputRange: [0, 1], 45 | outputRange: [SCREEN_HEIGHT - LOGIN_VIEW_HEIGHT, LOGIN_VIEW_HEIGHT / 2], 46 | }); 47 | 48 | useCode(() => 49 | cond(eq(gestureState.current, State.END), [ 50 | cond(eq(isOpen.current, 0), set(isOpen.current, 1)), 51 | ]), 52 | ); 53 | useCode(() => cond(eq(scale.current, 0), set(scale.current, 1)), []); 54 | 55 | return ( 56 | 57 | 58 | 59 | 60 | 67 | 68 | 69 | 78 | 79 | Get moving with Uber 80 | 81 | 82 | 83 | 84 | 88 | 92 | +91 93 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | ); 106 | } 107 | 108 | const styles = StyleSheet.create({ 109 | container: { 110 | flex: 1, 111 | backgroundColor: "#2289d6", 112 | }, 113 | logoContainer: { 114 | flex: 1, 115 | alignItems: "center", 116 | justifyContent: "center", 117 | }, 118 | heading: { 119 | alignItems: "flex-start", 120 | marginHorizontal: 25, 121 | marginTop: 50, 122 | }, 123 | image: { 124 | height: 24, 125 | width: 24, 126 | resizeMode: "contain", 127 | }, 128 | prefix: { 129 | fontSize: 20, 130 | paddingHorizontal: 10, 131 | }, 132 | textInput: { 133 | flex: 1, 134 | fontSize: 20, 135 | }, 136 | textInputContainer: { 137 | flexDirection: "row", 138 | margin: 25, 139 | }, 140 | }); 141 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-4/Constants.js: -------------------------------------------------------------------------------- 1 | import { Dimensions } from "react-native"; 2 | 3 | const { width, height } = Dimensions.get("window"); 4 | 5 | export const SCREEN_HEIGHT = height; 6 | export const SCREEN_WIDTH = width; 7 | 8 | export const TEXT_INPUT_HEIGHT = 150; 9 | export const FOOTER_HEIGHT = 70; 10 | 11 | export const LOGIN_VIEW_HEIGHT = TEXT_INPUT_HEIGHT + FOOTER_HEIGHT; 12 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-4/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "HelloWorld", 4 | "slug": "react-native-uber-ui", 5 | "platforms": [ 6 | "ios", 7 | "android", 8 | "web" 9 | ], 10 | "version": "1.0.0", 11 | "orientation": "portrait", 12 | "icon": "./assets/icon.png", 13 | "splash": { 14 | "image": "./assets/splash.png", 15 | "resizeMode": "contain", 16 | "backgroundColor": "#ffffff" 17 | }, 18 | "updates": { 19 | "fallbackToCacheTimeout": 0 20 | }, 21 | "assetBundlePatterns": [ 22 | "**/*" 23 | ], 24 | "ios": { 25 | "supportsTablet": true 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-4/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-4/assets/icon.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-4/assets/india.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-4/assets/india.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-4/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-4/assets/splash.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-4/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-4/components/Logo.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Animated from "react-native-reanimated"; 3 | import { View, Text, StyleSheet } from "react-native"; 4 | 5 | const Logo = ({ scale }) => ( 6 | 7 | Uber 8 | 9 | ); 10 | export default Logo; 11 | 12 | const styles = StyleSheet.create({ 13 | logo: { 14 | backgroundColor: "white", 15 | height: 120, 16 | width: 120, 17 | padding: 10, 18 | alignItems: "center", 19 | justifyContent: "center", 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-4/components/OverlayBg.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { View, Text, StyleSheet } from "react-native"; 3 | import Animated, { interpolate } from "react-native-reanimated"; 4 | import { LOGIN_VIEW_HEIGHT, SCREEN_HEIGHT } from "../Constants"; 5 | import { interpolateColor } from "react-native-redash"; 6 | const OverlayBg = ({ isOpenAnimation }) => { 7 | const translateY = interpolate(isOpenAnimation, { 8 | inputRange: [0, 1], 9 | outputRange: [SCREEN_HEIGHT - LOGIN_VIEW_HEIGHT, -LOGIN_VIEW_HEIGHT], 10 | }); 11 | 12 | const backgroundColor = interpolateColor(isOpenAnimation, { 13 | inputRange: [0, 0.5, 1], 14 | outputRange: ["#2289d6", "#FFFF", "#FFFF"], 15 | }); 16 | 17 | return ( 18 | 33 | ); 34 | }; 35 | export default OverlayBg; 36 | 37 | const styles = StyleSheet.create({ 38 | container: { 39 | flex: 1, 40 | alignItems: "center", 41 | justifyContent: "center", 42 | }, 43 | }); 44 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "web": "expo start --web", 8 | "eject": "expo eject" 9 | }, 10 | "dependencies": { 11 | "expo": "~37.0.3", 12 | "react": "~16.9.0", 13 | "react-dom": "~16.9.0", 14 | "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz", 15 | "react-native-gesture-handler": "^1.6.1", 16 | "react-native-reanimated": "^1.8.0", 17 | "react-native-redash": "^12.6.1", 18 | "react-native-web": "~0.11.7" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.8.6", 22 | "babel-preset-expo": "~8.1.0", 23 | "eslint-config-react-native-up": "^1.0.7", 24 | "eslint-plugin-react-hooks": "^3.0.0" 25 | }, 26 | "private": true 27 | } 28 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/App.js: -------------------------------------------------------------------------------- 1 | import React, { useRef } from "react"; 2 | import { StyleSheet, Text, View, Image } from "react-native"; 3 | import Logo from "./components/Logo"; 4 | import Animated, { 5 | useCode, 6 | cond, 7 | eq, 8 | set, 9 | interpolate, 10 | SpringUtils, 11 | } from "react-native-reanimated"; 12 | import { 13 | withTimingTransition, 14 | onGestureEvent, 15 | withSpringTransition, 16 | } from "react-native-redash"; 17 | import { SCREEN_HEIGHT, LOGIN_VIEW_HEIGHT } from "./Constants"; 18 | import { 19 | TextInput, 20 | TapGestureHandler, 21 | State, 22 | } from "react-native-gesture-handler"; 23 | import OverlayBg from "./components/OverlayBg"; 24 | import HeaderBackArrow from "./components/HeaderBackArrow"; 25 | import AnimatedPlaceholder from "./components/AnimatedPlaceholder"; 26 | 27 | export default function App() { 28 | const scale = useRef(new Animated.Value(0)); 29 | const scaleAnimation = withTimingTransition(scale.current); 30 | 31 | const innerLoginY = interpolate(scaleAnimation, { 32 | inputRange: [0, 1], 33 | outputRange: [LOGIN_VIEW_HEIGHT, 0], 34 | }); 35 | 36 | const gestureState = useRef(new Animated.Value(State.UNDETERMINED)); 37 | const gestureHandler = onGestureEvent({ state: gestureState.current }); 38 | 39 | const backArrowGestureState = useRef(new Animated.Value(State.UNDETERMINED)); 40 | const backArrowGestureHandler = onGestureEvent({ 41 | state: backArrowGestureState.current, 42 | }); 43 | 44 | const isOpen = useRef(new Animated.Value(0)); 45 | const isOpenAnimation = withSpringTransition(isOpen.current, { 46 | ...SpringUtils.makeDefaultConfig(), 47 | overshootClamping: true, 48 | damping: new Animated.Value(20), 49 | }); 50 | 51 | const outerLoginY = interpolate(isOpenAnimation, { 52 | inputRange: [0, 1], 53 | outputRange: [SCREEN_HEIGHT - LOGIN_VIEW_HEIGHT, LOGIN_VIEW_HEIGHT / 2], 54 | }); 55 | 56 | const headingOpacity = interpolate(isOpenAnimation, { 57 | inputRange: [0, 1], 58 | outputRange: [1, 0], 59 | }); 60 | 61 | useCode(() => 62 | cond( 63 | eq(gestureState.current, State.END), 64 | [cond(eq(isOpen.current, 0), set(isOpen.current, 1))], 65 | [gestureState.current], 66 | ), 67 | ); 68 | useCode(() => cond(eq(scale.current, 0), set(scale.current, 1)), []); 69 | 70 | useCode( 71 | () => 72 | cond(eq(backArrowGestureState.current, State.END), [ 73 | set(gestureState.current, State.UNDETERMINED), 74 | set(isOpen.current, 0), 75 | ]), 76 | [backArrowGestureState.current], 77 | ); 78 | 79 | return ( 80 | 81 | 82 | 83 | 84 | 88 | 89 | 96 | 97 | 98 | 107 | 110 | Get moving with Uber 111 | 112 | 113 | 114 | 115 | 119 | 120 | 124 | +91 125 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | ); 138 | } 139 | 140 | const styles = StyleSheet.create({ 141 | container: { 142 | flex: 1, 143 | backgroundColor: "#2289d6", 144 | }, 145 | logoContainer: { 146 | flex: 1, 147 | alignItems: "center", 148 | justifyContent: "center", 149 | }, 150 | heading: { 151 | alignItems: "flex-start", 152 | marginHorizontal: 25, 153 | marginTop: 50, 154 | }, 155 | image: { 156 | height: 24, 157 | width: 24, 158 | resizeMode: "contain", 159 | }, 160 | prefix: { 161 | fontSize: 20, 162 | paddingHorizontal: 10, 163 | }, 164 | textInput: { 165 | flex: 1, 166 | fontSize: 20, 167 | }, 168 | textInputContainer: { 169 | flexDirection: "row", 170 | margin: 25, 171 | }, 172 | }); 173 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/Constants.js: -------------------------------------------------------------------------------- 1 | import { Dimensions } from "react-native"; 2 | 3 | const { width, height } = Dimensions.get("window"); 4 | 5 | export const SCREEN_HEIGHT = height; 6 | export const SCREEN_WIDTH = width; 7 | 8 | export const TEXT_INPUT_HEIGHT = 150; 9 | export const FOOTER_HEIGHT = 70; 10 | 11 | export const LOGIN_VIEW_HEIGHT = TEXT_INPUT_HEIGHT + FOOTER_HEIGHT; 12 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "HelloWorld", 4 | "slug": "react-native-uber-ui", 5 | "platforms": [ 6 | "ios", 7 | "android", 8 | "web" 9 | ], 10 | "version": "1.0.0", 11 | "orientation": "portrait", 12 | "icon": "./assets/icon.png", 13 | "splash": { 14 | "image": "./assets/splash.png", 15 | "resizeMode": "contain", 16 | "backgroundColor": "#ffffff" 17 | }, 18 | "updates": { 19 | "fallbackToCacheTimeout": 0 20 | }, 21 | "assetBundlePatterns": [ 22 | "**/*" 23 | ], 24 | "ios": { 25 | "supportsTablet": true 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-5/assets/icon.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/assets/india.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-5/assets/india.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nathvarun/professional-animations-in-react-native/987d1be6644f8c774cf169c89f6fae4d4944734f/02-uber-login-screen/part-5/assets/splash.png -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/components/AnimatedPlaceholder.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { View, Text, StyleSheet } from "react-native"; 3 | import Animated, { interpolate } from "react-native-reanimated"; 4 | 5 | const AnimatedPlaceholder = ({ isOpenAnimation }) => { 6 | const translateX = interpolate(isOpenAnimation, { 7 | inputRange: [0, 1], 8 | outputRange: [80, 0], 9 | }); 10 | 11 | const translateY = interpolate(isOpenAnimation, { 12 | inputRange: [0, 0.5, 1], 13 | outputRange: [0, 0, -60], 14 | }); 15 | 16 | const opacity = interpolate(translateY, { 17 | inputRange: [-60, 0], 18 | outputRange: [1, 0], 19 | }); 20 | 21 | return ( 22 | 34 | Enter your mobile Number 35 | 36 | ); 37 | }; 38 | export default AnimatedPlaceholder; 39 | 40 | const styles = StyleSheet.create({ 41 | placeholder: { 42 | fontSize: 24, 43 | position: "absolute", 44 | }, 45 | }); 46 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/components/HeaderBackArrow.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { View, Text, StyleSheet } from "react-native"; 3 | import Animated, { interpolate } from "react-native-reanimated"; 4 | import { Ionicons as Icon } from "@expo/vector-icons"; 5 | import { TapGestureHandler } from "react-native-gesture-handler"; 6 | const HeaderBackArrow = ({ isOpenAnimation, gestureHandler }) => { 7 | const opacity = interpolate(isOpenAnimation, { 8 | inputRange: [0, 0.7, 1], 9 | outputRange: [0, 0, 1], 10 | }); 11 | 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | }; 20 | export default HeaderBackArrow; 21 | 22 | const styles = StyleSheet.create({ 23 | backArrow: { 24 | position: "absolute", 25 | height: 60, 26 | width: 60, 27 | top: 60, 28 | left: 25, 29 | zIndex: 100, 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/components/Logo.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Animated from "react-native-reanimated"; 3 | import { View, Text, StyleSheet } from "react-native"; 4 | 5 | const Logo = ({ scale }) => ( 6 | 7 | Uber 8 | 9 | ); 10 | export default Logo; 11 | 12 | const styles = StyleSheet.create({ 13 | logo: { 14 | backgroundColor: "white", 15 | height: 120, 16 | width: 120, 17 | padding: 10, 18 | alignItems: "center", 19 | justifyContent: "center", 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/components/OverlayBg.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { View, Text, StyleSheet } from "react-native"; 3 | import Animated, { interpolate } from "react-native-reanimated"; 4 | import { LOGIN_VIEW_HEIGHT, SCREEN_HEIGHT } from "../Constants"; 5 | import { interpolateColor } from "react-native-redash"; 6 | const OverlayBg = ({ isOpenAnimation }) => { 7 | const translateY = interpolate(isOpenAnimation, { 8 | inputRange: [0, 1], 9 | outputRange: [SCREEN_HEIGHT - LOGIN_VIEW_HEIGHT, -LOGIN_VIEW_HEIGHT], 10 | }); 11 | 12 | const backgroundColor = interpolateColor(isOpenAnimation, { 13 | inputRange: [0, 0.1, 1], 14 | outputRange: ["#2289d6", "#FFFF", "#FFFF"], 15 | }); 16 | 17 | return ( 18 | 33 | ); 34 | }; 35 | export default OverlayBg; 36 | 37 | const styles = StyleSheet.create({ 38 | container: { 39 | flex: 1, 40 | alignItems: "center", 41 | justifyContent: "center", 42 | }, 43 | }); 44 | -------------------------------------------------------------------------------- /02-uber-login-screen/part-5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "node_modules/expo/AppEntry.js", 3 | "scripts": { 4 | "start": "expo start", 5 | "android": "expo start --android", 6 | "ios": "expo start --ios", 7 | "web": "expo start --web", 8 | "eject": "expo eject" 9 | }, 10 | "dependencies": { 11 | "expo": "~37.0.3", 12 | "react": "~16.9.0", 13 | "react-dom": "~16.9.0", 14 | "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz", 15 | "react-native-gesture-handler": "^1.6.1", 16 | "react-native-reanimated": "^1.8.0", 17 | "react-native-redash": "^12.6.1", 18 | "react-native-web": "~0.11.7" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.8.6", 22 | "babel-preset-expo": "~8.1.0", 23 | "eslint-config-react-native-up": "^1.0.7", 24 | "eslint-plugin-react-hooks": "^3.0.0" 25 | }, 26 | "private": true 27 | } 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Performant-Animations-in-React-Native 2 | In this series we create real world high performant animations in react native 3 | --------------------------------------------------------------------------------