import 'dart:math' as math; import 'package:animated_text_kit/animated_text_kit.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:siro_rider/constant/box_name.dart'; import 'package:siro_rider/constant/colors.dart'; import 'package:siro_rider/constant/style.dart'; import 'package:siro_rider/main.dart'; import 'controller/home/splash_screen_controlle.dart'; class SplashScreen extends StatelessWidget { const SplashScreen({super.key}); @override Widget build(BuildContext context) { final controller = Get.put(SplashScreenController()); final size = MediaQuery.of(context).size; final isDark = Get.isDarkMode; final bg = isDark ? const Color(0xFF0A0F1E) : AppColor.primaryColor; final accent = AppColor.secondaryColorStatic; final gold = AppColor.gold; return SafeArea( child: Scaffold( backgroundColor: bg, body: Stack( children: [ // ── Animated gradient overlay ── Positioned.fill( child: AnimatedBuilder( animation: controller.glowAnimation, builder: (_, __) => Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ bg, Color.lerp(bg, accent.withOpacity(0.1), controller.glowAnimation.value)!, bg, ], ), ), ), ), ), // ── Top-right glow ── Positioned( top: -size.height * 0.14, right: -size.width * 0.18, child: Container( width: size.width * 0.75, height: size.width * 0.75, decoration: BoxDecoration( shape: BoxShape.circle, gradient: RadialGradient( colors: [ accent.withOpacity(0.08), Colors.transparent, ], ), ), ), ), // ── Bottom-left glow ── Positioned( bottom: -size.height * 0.08, left: -size.width * 0.2, child: Container( width: size.width * 0.65, height: size.width * 0.65, decoration: BoxDecoration( shape: BoxShape.circle, gradient: RadialGradient( colors: [ gold.withOpacity(0.05), Colors.transparent, ], ), ), ), ), // ── Subtle grid ── Positioned.fill( child: CustomPaint( painter: _GridPainter(color: accent.withOpacity(0.035)), ), ), // ── Main content ── Center( child: FadeTransition( opacity: controller.titleFadeAnimation, child: ScaleTransition( scale: controller.titleScaleAnimation, child: Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: 240, height: 240, child: Stack( alignment: Alignment.center, children: [ // Outer ring AnimatedBuilder( animation: controller.orbitAnimation, builder: (_, __) => Transform.rotate( angle: controller.orbitAnimation.value * 2 * math.pi, child: CustomPaint( painter: _OrbitalRingPainter( radius: 108, dotColor: accent, lineOpacity: 0.2, dotSize: 5, ), size: const Size(240, 240), ), ), ), // Inner ring AnimatedBuilder( animation: controller.orbitAnimation, builder: (_, __) => Transform.rotate( angle: -controller.orbitAnimation.value * 2 * math.pi * 0.65, child: CustomPaint( painter: _OrbitalRingPainter( radius: 76, dotColor: gold, lineOpacity: 0.14, dotSize: 4, dashCount: 16, ), size: const Size(240, 240), ), ), ), // Center glow AnimatedBuilder( animation: controller.glowAnimation, builder: (_, __) => Container( width: 80, height: 80, decoration: BoxDecoration( shape: BoxShape.circle, boxShadow: [ BoxShadow( color: accent.withOpacity(0.1 + controller.glowAnimation.value * 0.18), blurRadius: 30 + controller.glowAnimation.value * 25, spreadRadius: 0, ), ], ), ), ), // Siro text AnimatedTextKit( animatedTexts: [ ColorizeAnimatedText( 'Siro', textStyle: const TextStyle( fontSize: 40, fontWeight: FontWeight.w800, letterSpacing: 5, height: 1, ), colors: [ Colors.white, accent, gold.withOpacity(0.85), Colors.white, ], speed: const Duration(milliseconds: 500), ), ], isRepeatingAnimation: false, ), ], ), ), const SizedBox(height: 24), // Tagline FadeTransition( opacity: controller.taglineFadeAnimation, child: SlideTransition( position: controller.taglineSlideAnimation, child: Column( children: [ _TaglineBadge( controller: controller, accent: accent), const SizedBox(height: 14), Text( 'Your Journey Begins Here'.tr, style: TextStyle( color: Colors.white.withOpacity(0.4), fontSize: 13, letterSpacing: 1, fontWeight: FontWeight.w300, ), ), ], ), ), ), ], ), ), ), ), // ── Bottom ── Positioned( left: 32, right: 32, bottom: 48, child: FadeTransition( opacity: controller.footerFadeAnimation, child: Column( mainAxisSize: MainAxisSize.min, children: [ Obx(() => _GlowProgressBar( value: controller.progress.value, accent: accent)), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('SIRO', style: TextStyle( fontSize: 9, fontWeight: FontWeight.w700, color: Colors.white.withOpacity(0.12), letterSpacing: 4.5)), Text('v${box.read(BoxName.packagInfo) ?? '1.0.0'}', style: TextStyle( fontSize: 9, fontWeight: FontWeight.w500, color: Colors.white.withOpacity(0.12), letterSpacing: 1.5)), ], ), ], ), ), ), ], ), ), ); } } // ── Tagline badge ── class _TaglineBadge extends StatelessWidget { final SplashScreenController controller; final Color accent; const _TaglineBadge({required this.controller, required this.accent}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 5), decoration: BoxDecoration( border: Border.all(color: accent.withOpacity(0.25), width: 1), borderRadius: BorderRadius.circular(20), color: accent.withOpacity(0.05), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ AnimatedBuilder( animation: controller.glowAnimation, builder: (_, __) => Container( width: 6, height: 6, decoration: BoxDecoration( shape: BoxShape.circle, color: accent .withOpacity(0.4 + controller.glowAnimation.value * 0.6), boxShadow: [ BoxShadow( color: accent .withOpacity(controller.glowAnimation.value * 0.5), blurRadius: 6, spreadRadius: 1), ], ), ), ), const SizedBox(width: 8), Text('AI-Powered Mobility', style: TextStyle( fontSize: 11, fontWeight: FontWeight.w600, color: accent.withOpacity(0.85), letterSpacing: 1.4)), ], ), ); } } // ── Progress bar ── class _GlowProgressBar extends StatelessWidget { final double value; final Color accent; const _GlowProgressBar({required this.value, required this.accent}); @override Widget build(BuildContext context) { return Stack( children: [ Container( height: 2, decoration: BoxDecoration( color: Colors.white.withOpacity(0.06), borderRadius: BorderRadius.circular(2))), FractionallySizedBox( widthFactor: value.clamp(0.0, 1.0), child: Container( height: 2, decoration: BoxDecoration( gradient: LinearGradient(colors: [accent.withOpacity(0.5), accent]), borderRadius: BorderRadius.circular(2), boxShadow: [ BoxShadow( color: accent.withOpacity(0.4), blurRadius: 8, spreadRadius: 1) ], ), ), ), ], ); } } // ── Grid painter ── class _GridPainter extends CustomPainter { final Color color; _GridPainter({required this.color}); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = color ..strokeWidth = 0.5; const step = 36.0; for (double y = 0; y < size.height; y += step) { canvas.drawLine(Offset(0, y), Offset(size.width, y), paint); } for (double x = 0; x < size.width; x += step) { canvas.drawLine(Offset(x, 0), Offset(x, size.height), paint); } } @override bool shouldRepaint(_GridPainter old) => old.color != color; } // ── Orbital ring ── class _OrbitalRingPainter extends CustomPainter { final double radius; final Color dotColor; final double lineOpacity; final double dotSize; final int dashCount; const _OrbitalRingPainter({ this.radius = 95, this.dotColor = const Color(0xFF8C9CF8), this.lineOpacity = 0.20, this.dotSize = 5.5, this.dashCount = 0, }); @override void paint(Canvas canvas, Size size) { final center = Offset(size.width / 2, size.height / 2); if (dashCount > 0) { final dashPaint = Paint() ..color = dotColor.withOpacity(lineOpacity) ..strokeWidth = 1 ..style = PaintingStyle.stroke ..strokeCap = StrokeCap.round; for (int i = 0; i < dashCount; i++) { final start = i * (2 * math.pi / dashCount); final sweep = (2 * math.pi / dashCount) * 0.55; canvas.drawArc(Rect.fromCircle(center: center, radius: radius), start, sweep, false, dashPaint); } } else { final ringPaint = Paint() ..color = dotColor.withOpacity(lineOpacity) ..strokeWidth = 1 ..style = PaintingStyle.stroke; canvas.drawCircle(center, radius, ringPaint); } final dotPos = Offset(center.dx, center.dy - radius); final glowPaint = Paint() ..color = dotColor.withOpacity(0.30) ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 9); canvas.drawCircle(dotPos, dotSize + 2, glowPaint); canvas.drawCircle( dotPos, dotSize, Paint() ..color = dotColor ..style = PaintingStyle.fill); } @override bool shouldRepaint(_OrbitalRingPainter old) => false; }