import 'package:flutter/material.dart'; import 'dart:async'; import 'dashboard_screen_with_api.dart'; class SplashScreen extends StatefulWidget { const SplashScreen({super.key}); @override SplashScreenState createState() => SplashScreenState(); } class SplashScreenState extends State with SingleTickerProviderStateMixin { late AnimationController _animationController; late Animation _fadeAnimation; late Animation _scaleAnimation; @override void initState() { super.initState(); // Setup animation controller _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 1500), ); // Fade animation _fadeAnimation = Tween(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: _animationController, curve: const Interval(0.0, 0.6, curve: Curves.easeIn), ), ); // Scale animation _scaleAnimation = Tween(begin: 0.5, end: 1.0).animate( CurvedAnimation( parent: _animationController, curve: const Interval(0.0, 0.6, curve: Curves.easeOutBack), ), ); // Start animation _animationController.forward(); // Navigate to dashboard after delay Timer(const Duration(seconds: 3), () { if (mounted) { Navigator.pushReplacement( context, PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) => const DashboardScreenWithApi(), transitionsBuilder: (context, animation, secondaryAnimation, child) { const begin = Offset(1.0, 0.0); const end = Offset.zero; const curve = Curves.easeInOut; var tween = Tween(begin: begin, end: end) .chain(CurveTween(curve: curve)); var offsetAnimation = animation.drive(tween); return SlideTransition( position: offsetAnimation, child: child, ); }, transitionDuration: const Duration(milliseconds: 500), ), ); } }); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Colors.blue.shade700, Colors.blue.shade400, Colors.lightBlue.shade300, ], ), ), child: Center( child: AnimatedBuilder( animation: _animationController, builder: (context, child) { return FadeTransition( opacity: _fadeAnimation, child: ScaleTransition( scale: _scaleAnimation, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Icon/Logo - Gambar Ikan Container( width: 160, height: 160, padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 20, spreadRadius: 5, ), ], ), child: CustomPaint( painter: FishPainter(), ), ), const SizedBox(height: 40), // App Name const Text( "Pengering Ikan", style: TextStyle( fontSize: 32, fontWeight: FontWeight.bold, color: Colors.white, letterSpacing: 1.5, ), ), const SizedBox(height: 10), // Subtitle const Text( "Monitoring System", style: TextStyle( fontSize: 16, color: Colors.white70, letterSpacing: 0.5, ), ), const SizedBox(height: 50), // Loading indicator const SizedBox( width: 40, height: 40, child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Colors.white), strokeWidth: 3, ), ), const SizedBox(height: 20), const Text( "Loading...", style: TextStyle( fontSize: 14, color: Colors.white70, ), ), ], ), ), ); }, ), ), ), ); } } // Custom Painter untuk gambar ikan class FishPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = Colors.blue.shade700 ..style = PaintingStyle.fill ..isAntiAlias = true; // Badan ikan (oval) - lebih kecil dan centered final bodyRect = Rect.fromLTWH( size.width * 0.3, // Lebih ke kanan size.height * 0.35, // Lebih ke tengah size.width * 0.5, // Lebih kecil size.height * 0.3, // Lebih kecil ); canvas.drawOval(bodyRect, paint); // Ekor ikan (segitiga) - adjust posisi final tailPath = Path(); tailPath.moveTo(size.width * 0.3, size.height * 0.5); // Kiri tengah tailPath.lineTo(size.width * 0.1, size.height * 0.4); // Atas kiri tailPath.lineTo(size.width * 0.1, size.height * 0.6); // Bawah kiri tailPath.close(); canvas.drawPath(tailPath, paint); // Mata ikan (lingkaran kecil putih) - adjust posisi final eyePaint = Paint() ..color = Colors.white ..style = PaintingStyle.fill ..isAntiAlias = true; canvas.drawCircle( Offset(size.width * 0.65, size.height * 0.47), size.width * 0.05, eyePaint, ); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; }