import React, {useCallback, useEffect} from 'react' import {View, StyleSheet} from 'react-native' import * as SplashScreen from 'expo-splash-screen' import LinearGradient from 'react-native-linear-gradient' import Animated, { interpolate, runOnJS, useAnimatedStyle, useSharedValue, withTiming, Easing, } from 'react-native-reanimated' import MaskedView from '@react-native-masked-view/masked-view' import {useSafeAreaInsets} from 'react-native-safe-area-context' import Svg, {Path, SvgProps} from 'react-native-svg' export const Logo = React.forwardRef(function LogoImpl(props: SvgProps, ref) { const width = 1000 const height = width * (67 / 64) return ( ) }) type Props = { isReady: boolean } SplashScreen.preventAutoHideAsync().catch(() => {}) const AnimatedLogo = Animated.createAnimatedComponent(Logo) export function Splash(props: React.PropsWithChildren) { const insets = useSafeAreaInsets() const intro = useSharedValue(0) const outroLogo = useSharedValue(0) const outroApp = useSharedValue(0) const [isAnimationComplete, setIsAnimationComplete] = React.useState(false) const logoAnimations = useAnimatedStyle(() => { return { transform: [ { scale: interpolate(intro.value, [0, 1], [0.8, 1], 'clamp'), }, { scale: interpolate( outroLogo.value, [0, 0.06, 0.08, 1], [1, 0.8, 0.8, 800], 'clamp', ), }, ], opacity: interpolate(intro.value, [0, 1], [0, 1], 'clamp'), } }) const appAnimation = useAnimatedStyle(() => { return { transform: [ { scale: interpolate( outroApp.value, [0, 0.7, 1], [1.1, 1.1, 1], 'clamp', ), }, ], opacity: interpolate(outroApp.value, [0, 0.7, 1], [0, 0, 1], 'clamp'), } }) const onFinish = useCallback(() => setIsAnimationComplete(true), []) useEffect(() => { if (props.isReady) { // hide on mount SplashScreen.hideAsync().catch(() => {}) intro.value = withTiming( 1, {duration: 200, easing: Easing.out(Easing.cubic)}, async () => { outroLogo.value = withTiming( 1, {duration: 1200, easing: Easing.in(Easing.cubic)}, () => { runOnJS(onFinish)() }, ) outroApp.value = withTiming( 1, {duration: 1200, easing: Easing.inOut(Easing.cubic)}, () => { runOnJS(onFinish)() }, ) }, ) } }, [onFinish, intro, outroLogo, outroApp, props.isReady]) return ( {!isAnimationComplete && ( )} }> {!isAnimationComplete && ( )} {props.children} ) }