mirror of
https://github.com/zhigang1992/examples.git
synced 2026-01-12 22:47:03 +08:00
Merge pull request #95 from byCedric/feat/splash-screen-animation
feat: add animated splash screen example
This commit is contained in:
130
with-animated-splash-screen/App.js
Normal file
130
with-animated-splash-screen/App.js
Normal 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>
|
||||
);
|
||||
}
|
||||
24
with-animated-splash-screen/README.md
Normal file
24
with-animated-splash-screen/README.md
Normal 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/)
|
||||
12
with-animated-splash-screen/app.json
Normal file
12
with-animated-splash-screen/app.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
6
with-animated-splash-screen/babel.config.js
Normal file
6
with-animated-splash-screen/babel.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = function(api) {
|
||||
api.cache(true);
|
||||
return {
|
||||
presets: ['babel-preset-expo'],
|
||||
};
|
||||
};
|
||||
15
with-animated-splash-screen/package.json
Normal file
15
with-animated-splash-screen/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user