import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import '../../../core/constants/app_colors.dart'; import '../../../core/constants/app_typography.dart'; import '../../../core/constants/app_constants.dart'; class SplashScreen extends StatefulWidget { const SplashScreen({super.key}); @override State createState() => _SplashScreenState(); } class _SplashScreenState extends State with TickerProviderStateMixin { late List _foodControllers; late AnimationController _questionMarkController; late AnimationController _centerIconController; final List foodIcons = [ Icons.rice_bowl, Icons.ramen_dining, Icons.lunch_dining, Icons.fastfood, Icons.local_pizza, Icons.cake, Icons.coffee, Icons.icecream, Icons.bakery_dining, ]; @override void initState() { super.initState(); _initializeAnimations(); _navigateToHome(); } void _initializeAnimations() { // 음식 아이콘 애니메이션 (여러 개) _foodControllers = List.generate( foodIcons.length, (index) => AnimationController( duration: Duration(seconds: 2 + index % 3), vsync: this, )..repeat(reverse: true), ); // 물음표 애니메이션 _questionMarkController = AnimationController( duration: const Duration(milliseconds: 500), vsync: this, )..repeat(); // 중앙 아이콘 애니메이션 _centerIconController = AnimationController( duration: const Duration(seconds: 1), vsync: this, )..repeat(reverse: true); } @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; return Scaffold( backgroundColor: isDark ? AppColors.darkBackground : AppColors.lightBackground, body: Stack( children: [ // 랜덤 위치 음식 아이콘들 ..._buildFoodIcons(), // 중앙 컨텐츠 Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // 선택 아이콘 ScaleTransition( scale: Tween(begin: 0.8, end: 1.2).animate( CurvedAnimation( parent: _centerIconController, curve: Curves.easeInOut, ), ), child: Icon( Icons.restaurant_menu, size: 80, color: isDark ? AppColors.darkPrimary : AppColors.lightPrimary, ), ), const SizedBox(height: 20), // 앱 타이틀 Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('오늘 뭐 먹Z', style: AppTypography.heading1(isDark)), AnimatedBuilder( animation: _questionMarkController, builder: (context, child) { final questionMarks = '?' * (((_questionMarkController.value * 3).floor() % 3) + 1); return Text( questionMarks, style: AppTypography.heading1(isDark), ); }, ), ], ), ], ), ), // 하단 카피라이트 Positioned( bottom: 30, left: 0, right: 0, child: Text( AppConstants.appCopyright, style: AppTypography.caption(isDark).copyWith( color: (isDark ? AppColors.darkTextSecondary : AppColors.lightTextSecondary) .withOpacity(0.5), ), textAlign: TextAlign.center, ), ), ], ), ); } List _buildFoodIcons() { final random = math.Random(); return List.generate(foodIcons.length, (index) { final left = random.nextDouble() * 0.8 + 0.1; final top = random.nextDouble() * 0.7 + 0.1; return Positioned( left: MediaQuery.of(context).size.width * left, top: MediaQuery.of(context).size.height * top, child: FadeTransition( opacity: Tween(begin: 0.2, end: 0.8).animate( CurvedAnimation( parent: _foodControllers[index], curve: Curves.easeInOut, ), ), child: ScaleTransition( scale: Tween(begin: 0.5, end: 1.5).animate( CurvedAnimation( parent: _foodControllers[index], curve: Curves.easeInOut, ), ), child: Icon( foodIcons[index], size: 40, color: AppColors.lightPrimary.withOpacity(0.3), ), ), ), ); }); } void _navigateToHome() { Future.delayed(AppConstants.splashAnimationDuration, () { if (mounted) { context.go('/home'); } }); } @override void dispose() { for (final controller in _foodControllers) { controller.dispose(); } _questionMarkController.dispose(); _centerIconController.dispose(); super.dispose(); } }