Merge pull request #95 from byCedric/feat/splash-screen-animation

feat: add animated splash screen example
This commit is contained in:
Evan Bacon
2020-02-20 12:31:08 -08:00
committed by GitHub
5 changed files with 187 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
import { AppLoading, SplashScreen, Updates } from 'expo';
import { Asset } from 'expo-asset';
import Constants from 'expo-constants';
import React from 'react';
import { Animated, Button, StyleSheet, Text, View } from 'react-native';
// Instruct SplashScreen not to hide yet, we want to do this manually
SplashScreen.preventAutoHide();
export default function App() {
return (
<AnimatedAppLoader image={{ uri: Constants.manifest.splash.image }}>
<MainScreen />
</AnimatedAppLoader>
);
}
function AnimatedAppLoader({ children, image }) {
const [isSplashReady, setSplashReady] = React.useState(false);
const startAsync = React.useMemo(
// If you use a local image with require(...), use `Asset.fromModule`
() => () => Asset.fromURI(image).downloadAsync(),
[image]
);
const onFinish = React.useMemo(() => setSplashReady(true), []);
if (!isSplashReady) {
return (
<AppLoading
startAsync={startAsync}
onError={console.error}
onFinish={onFinish}
/>
);
}
return (
<AnimatedSplashScreen image={image}>
{children}
</AnimatedSplashScreen>
);
}
function AnimatedSplashScreen({ children, image }) {
const animation = React.useMemo(() => new Animated.Value(1), []);
const [isAppReady, setAppReady] = React.useState(false);
const [isSplashAnimationComplete, setAnimationComplete] = React.useState(
false
);
React.useEffect(() => {
if (isAppReady) {
Animated.timing(animation, {
toValue: 0,
duration: 200,
useNativeDriver: true,
}).start(() => setAnimationComplete(true));
}
}, [isAppReady]);
const onImageLoaded = React.useMemo(() => async () => {
SplashScreen.hide();
try {
// Load stuff
await Promise.all([]);
} catch (e) {
// handle errors
} finally {
setAppReady(true);
}
});
return (
<View style={{ flex: 1 }}>
{isAppReady && children}
{!isSplashAnimationComplete && (
<Animated.View
pointerEvents="none"
style={[
StyleSheet.absoluteFill,
{
backgroundColor: Constants.manifest.splash.backgroundColor,
opacity: animation,
},
]}>
<Animated.Image
style={{
width: '100%',
height: '100%',
resizeMode: Constants.manifest.splash.resizeMode || 'contain',
transform: [
{
scale: animation,
},
],
}}
source={image}
onLoadEnd={onImageLoaded}
fadeDuration={0}
/>
</Animated.View>
)}
</View>
);
}
function MainScreen() {
return (
<View
style={{
flex: 1,
backgroundColor: 'plum',
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
color: 'black',
fontSize: 30,
marginBottom: 15,
fontWeight: 'bold',
}}>
Pretty Cool!
</Text>
<Button title="Run Again" onPress={() => Updates.reload()} />
</View>
);
}

View File

@@ -0,0 +1,24 @@
# Animated Splash Screen Example
<p>
<!-- iOS -->
<img alt="Supports Expo iOS" longdesc="Supports Expo iOS" src="https://img.shields.io/badge/iOS-4630EB.svg?style=flat-square&logo=APPLE&labelColor=999999&logoColor=fff" />
<!-- Android -->
<img alt="Supports Expo Android" longdesc="Supports Expo Android" src="https://img.shields.io/badge/Android-4630EB.svg?style=flat-square&logo=ANDROID&labelColor=A4C639&logoColor=fff" />
<!-- Web -->
<img alt="Supports Expo Web" longdesc="Supports Expo Web" src="https://img.shields.io/badge/web-4630EB.svg?style=flat-square&logo=GOOGLE-CHROME&labelColor=4285F4&logoColor=fff" />
</p>
This example shows you how to create an animated splash screen for your app. It uses the app loading to load the assets required for the animation. Once that's loaded, it replaces the app loading with a custom component that loads the rest of your app. When all of this is finished, it uses an outro animation and renders the app.
## 🚀 How to use
- Run `yarn` or `npm install`
- Run [`expo start`](https://docs.expo.io/versions/latest/workflow/expo-cli/), try it out.
- Wait until the app is built and downloaded. Press "run again" to reload the app and splash screen.
## 📝 Notes
- [Expo AppLoading docs](https://docs.expo.io/versions/latest/sdk/app-loading/)
- [Expo Assets guide](https://docs.expo.io/versions/latest/guides/assets/)
- [Expo Splash Screen guide](https://docs.expo.io/versions/latest/guides/splash-screens/)

View File

@@ -0,0 +1,12 @@
{
"expo": {
"name": "with-animated-splash-screen",
"version": "1.0.0",
"icon": "https://github.com/expo/expo/blob/master/templates/expo-template-blank/assets/icon.png?raw=true",
"splash": {
"image": "https://github.com/expo/expo/blob/master/templates/expo-template-blank/assets/splash.png?raw=true",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
}
}
}

View File

@@ -0,0 +1,6 @@
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};

View File

@@ -0,0 +1,15 @@
{
"dependencies": {
"expo": "36.0.0",
"expo-asset": "8.0.0",
"expo-constants": "8.0.0",
"react": "16.9.0",
"react-dom": "16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz",
"react-native-web": "0.11.7"
},
"devDependencies": {
"@babel/core": "7.0.0",
"babel-preset-expo": "8.0.0"
}
}