From 4180c3047bf75e1afee6a0428b0f2c1cd4aab0bb Mon Sep 17 00:00:00 2001 From: suzzzal Date: Tue, 20 Jan 2026 23:21:09 +0530 Subject: [PATCH] Refactor onboarding screen and animations Refactor GettingStartedScreen to App component with updated animations and layout adjustments. --- .../app/(onboarding)/getting-started.tsx | 273 ++++++++++-------- 1 file changed, 152 insertions(+), 121 deletions(-) diff --git a/apps/mobile/app/(onboarding)/getting-started.tsx b/apps/mobile/app/(onboarding)/getting-started.tsx index f13725e..6fb4743 100644 --- a/apps/mobile/app/(onboarding)/getting-started.tsx +++ b/apps/mobile/app/(onboarding)/getting-started.tsx @@ -1,196 +1,227 @@ import { useEffect, useRef } from 'react'; -import { View, Text, Pressable, Image, Animated } from 'react-native'; -import { SafeAreaView } from 'react-native-safe-area-context'; -import { router } from 'expo-router'; +import { View, Text, Pressable, Animated } from 'react-native'; +import { + SafeAreaView, + SafeAreaProvider, +} from 'react-native-safe-area-context'; import { Ionicons } from '@expo/vector-icons'; -export default function GettingStartedScreen() { - const fadeAnim = useRef(new Animated.Value(0)).current; - const slideAnim = useRef(new Animated.Value(50)).current; - const logoScale = useRef(new Animated.Value(0.5)).current; - const logoRotate = useRef(new Animated.Value(0)).current; - const titleSlide = useRef(new Animated.Value(30)).current; +export default function App() { + const containerFade = useRef(new Animated.Value(0)).current; + const containerSlide = useRef(new Animated.Value(40)).current; + + const logoScale = useRef(new Animated.Value(0.85)).current; + const logoIdle = useRef(new Animated.Value(1)).current; + const titleFade = useRef(new Animated.Value(0)).current; - const descriptionSlide = useRef(new Animated.Value(20)).current; - const descriptionFade = useRef(new Animated.Value(0)).current; - const buttonScale = useRef(new Animated.Value(0.9)).current; - const buttonOpacity = useRef(new Animated.Value(0)).current; - const buttonSlide = useRef(new Animated.Value(20)).current; - const footerFade = useRef(new Animated.Value(0)).current; + const titleSlide = useRef(new Animated.Value(24)).current; - // Add breathing effect to logo after initial animation - const breathingAnimation = useRef(new Animated.Value(1)).current; + const descFade = useRef(new Animated.Value(0)).current; + const descSlide = useRef(new Animated.Value(20)).current; + + const buttonFade = useRef(new Animated.Value(0)).current; + const buttonSlide = useRef(new Animated.Value(16)).current; + + const footerFade = useRef(new Animated.Value(0)).current; useEffect(() => { - // Main animation sequence Animated.sequence([ - // Stage 1: Container fade in and logo entrance Animated.parallel([ - Animated.timing(fadeAnim, { + Animated.timing(containerFade, { toValue: 1, - duration: 800, + duration: 600, useNativeDriver: true, }), - Animated.timing(slideAnim, { + Animated.timing(containerSlide, { toValue: 0, - duration: 800, + duration: 600, useNativeDriver: true, }), Animated.spring(logoScale, { toValue: 1, - tension: 40, - friction: 8, - useNativeDriver: true, - }), - Animated.timing(logoRotate, { - toValue: 1, - duration: 800, + tension: 30, + friction: 10, useNativeDriver: true, }), ]), - - // Stage 2: Title animation Animated.parallel([ Animated.timing(titleFade, { toValue: 1, - duration: 600, + duration: 500, useNativeDriver: true, }), Animated.spring(titleSlide, { toValue: 0, - tension: 50, - friction: 8, + tension: 40, + friction: 9, useNativeDriver: true, }), ]), - - // Stage 3: Description animation Animated.parallel([ - Animated.timing(descriptionFade, { + Animated.timing(descFade, { toValue: 1, - duration: 500, + duration: 450, useNativeDriver: true, }), - Animated.spring(descriptionSlide, { + Animated.spring(descSlide, { toValue: 0, - tension: 50, - friction: 8, + tension: 40, + friction: 9, useNativeDriver: true, }), ]), - ]).start(() => { - // Stage 4: Button and footer animation Animated.parallel([ - Animated.spring(buttonScale, { + Animated.timing(buttonFade, { toValue: 1, - tension: 60, - friction: 7, - useNativeDriver: true, - }), - Animated.timing(buttonOpacity, { - toValue: 1, - duration: 500, + duration: 400, useNativeDriver: true, }), Animated.timing(buttonSlide, { toValue: 0, - duration: 500, + duration: 400, useNativeDriver: true, }), Animated.timing(footerFade, { toValue: 1, - duration: 600, - delay: 200, + duration: 400, + delay: 100, useNativeDriver: true, }), - ]).start(() => { - // Start breathing animation for logo after everything loads + ]), + ]).start(() => { + setTimeout(() => { Animated.loop( Animated.sequence([ - Animated.timing(breathingAnimation, { - toValue: 1.05, - duration: 2000, + Animated.timing(logoIdle, { + toValue: 1.03, + duration: 3000, useNativeDriver: true, }), - Animated.timing(breathingAnimation, { + Animated.timing(logoIdle, { toValue: 1, - duration: 2000, + duration: 3000, useNativeDriver: true, }), ]) ).start(); - }); + }, 800); }); }, []); - const logoRotateInterpolate = logoRotate.interpolate({ - inputRange: [0, 1], - outputRange: ['-10deg', '0deg'], - }); - return ( - - - + + + > + - - - Learn Smarter with Blob - + + + Learn Smarter with Blob + + + + + + Your AI-powered study companion. Transform notes into interactive + flashcards and quizzes instantly. + + - - Your AI-powered study companion. Transform notes into interactive flashcards and quizzes - instantly. - - - - - - router.push('/(onboarding)/login')}> - Continue - - + paddingHorizontal: 24, + paddingBottom: 32, + opacity: buttonFade, + transform: [{ translateY: buttonSlide }], + }} + > + console.log('Continue pressed')} + > + + Continue + + + - - + By continuing, you agree to our Terms and Privacy Policy - + - - + + ); }