Greenlens/components/AnimatedSplashScreen.tsx

61 lines
2.8 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { StyleSheet } from 'react-native';
import { Video, ResizeMode } from 'expo-av';
import * as SplashScreen from 'expo-splash-screen';
import Animated, { FadeOut } from 'react-native-reanimated';
import { useApp } from '../context/AppContext';
import { useColors } from '../constants/Colors';
interface Props {
isAppReady: boolean;
onAnimationComplete: () => void;
}
export function AnimatedSplashScreen({ isAppReady, onAnimationComplete }: Props) {
const [hasPlayedEnough, setHasPlayedEnough] = useState(false);
useEffect(() => {
// Ensure the video plays for at least 2 seconds before we allow it to finish,
// so it doesn't flash too fast and provides a premium feel.
const timer = setTimeout(() => {
setHasPlayedEnough(true);
}, 2000);
return () => clearTimeout(timer);
}, []);
useEffect(() => {
if (isAppReady && hasPlayedEnough) {
onAnimationComplete();
}
}, [isAppReady, hasPlayedEnough, onAnimationComplete]);
// Determine the background color to blend perfectly
const { isDarkMode, colorPalette } = useApp();
const colors = useColors(isDarkMode, colorPalette);
return (
<Animated.View exiting={FadeOut.duration(600)} style={[StyleSheet.absoluteFill, { zIndex: 9999, backgroundColor: colors.background, alignItems: 'center', justifyContent: 'center' }]}>
<Animated.View style={{ width: 220, height: 220, borderRadius: 45, overflow: 'hidden', backgroundColor: colors.surface, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.15, shadowRadius: 15, elevation: 8, transform: [{ scale: 1 }] }}>
<Video
source={require('../assets/Make_some_light_leaf_animations_delpmaspu_.mp4')}
style={{ width: '100%', height: '100%' }}
resizeMode={ResizeMode.COVER}
shouldPlay
isMuted
isLooping
rate={2.0} // Play at 2x speed to make the 8-second video feel punchier as a loading screen
onReadyForDisplay={() => {
// Instantly hide the native static splash screen as soon as the video is painted
SplashScreen.hideAsync().catch(() => { });
}}
onError={(err) => {
console.error("Video loading error:", err);
// Fallback in case the video fails to load for any reason
SplashScreen.hideAsync().catch(() => { });
onAnimationComplete();
}}
/>
</Animated.View>
</Animated.View>
);
}