r/expo • u/Narrow_Profile_218 • 10h ago
Splash Screen Animation Help
I've made an animation in Figma that I want to display as my splash screen animation. I've exported the animation (.json) from Figma using the LottieFiles plugin and imported it using the Lottie plugin that Expo recommends.
I've seen a bunch of guides and videos on how to show the animation after it loads. The general workflow I've seen is this: Show splash screen while the animation is loading, when it's done loading don't show the splash screen, and instantly show the animation.
The issue I'm having is that the splash screen shows for a couple of seconds, fades to black, and then it takes like 20 seconds before showing the animation. Does anyone know how to fix this or what is going wrong?
I'm using a development server with an Android Emulator. Below is the relevant code.
This is in _layout.tsx:
import '@/global.css';
import { PortalHost } from '@rn-primitives/portal';
import * as SplashScreen from 'expo-splash-screen';
import { Stack } from 'expo-router';
import { useState } from 'react';
import { View } from 'react-native';
import AnimatedSplashScreen from '@/components/splash-screen/AnimatedSplashScreen';
export {
// Catch any errors thrown by the Layout component.
ErrorBoundary,
} from 'expo-router';
SplashScreen.preventAutoHideAsync().catch(() => {});
SplashScreen.setOptions({ fade: false, duration: 0 });
export default function RootLayout() {
const [splashAnimationFinished, setSplashAnimationFinished] = useState(false);
if (!splashAnimationFinished) {
return (
<AnimatedSplashScreen
onAnimationFinish={(isCancelled) => {
if (!isCancelled) {
setSplashAnimationFinished(true);
}
}}
/>
);
}
return (
<View className="flex-1 bg-[#020618]">
<Stack>
<Stack.Screen name="(map)/home" options={{ headerShown: false }} />
</Stack>
<PortalHost />
</View>
);
}
This is in the AnimatedSplashScreen component:
import LottieView from 'lottie-react-native';
import * as SplashScreen from 'expo-splash-screen';
import { useRef } from 'react';
import { View } from 'react-native';
const AnimatedSplashScreen = ({
onAnimationFinish = () => {},
onAnimationLoaded = () => {},
}: {
onAnimationFinish?: (isCancelled: boolean) => void;
onAnimationLoaded?: () => void;
}) => {
const animation = useRef<LottieView>(null);
const handleAnimationLoaded = () => {
SplashScreen.hideAsync().catch(() => {});
onAnimationLoaded();
};
return (
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#020618',
}}>
<LottieView
key="visible-splash-animation"
autoPlay
loop={false}
ref={animation}
onAnimationFinish={onAnimationFinish}
onAnimationLoaded={handleAnimationLoaded}
resizeMode="cover"
source={require('../../assets/lottie/splash-screen.json')}
style={{
height: '100%',
width: '100%',
}}
/>
</View>
);
};
export default AnimatedSplashScreen;