import 'dart:math' as math;
import 'package:flutter/[Link]';
import '../[Link]';
import 'login_screen.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({[Link]});
@override
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen>
with TickerProviderStateMixin {
late AnimationController _ringController;
late AnimationController _fadeController;
late AnimationController _slideController;
late Animation<double> _ringAnimation;
late Animation<double> _fadeAnimation;
late Animation<Offset> _slideAnimation;
late Animation<double> _scaleAnimation;
@override
void initState() {
[Link]();
_ringController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1800),
);
_fadeController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 800),
);
_slideController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 900),
);
_ringAnimation = CurvedAnimation(
parent: _ringController,
curve: [Link],
);
_fadeAnimation = CurvedAnimation(
parent: _fadeController,
curve: [Link],
);
_slideAnimation = Tween<Offset>(
begin: const Offset(0, 0.4),
end: [Link],
).animate(CurvedAnimation(
parent: _slideController,
curve: [Link],
));
_scaleAnimation = Tween<double>(begin: 0.6, end: 1.0).animate(
CurvedAnimation(parent: _ringController, curve: [Link]),
);
_startAnimation();
}
void _startAnimation() async {
await [Link](const Duration(milliseconds: 200));
_ringController.forward();
await [Link](const Duration(milliseconds: 600));
_fadeController.forward();
_slideController.forward();
await [Link](const Duration(milliseconds: 2200));
if (mounted) {
[Link](context).pushReplacement(
PageRouteBuilder(
pageBuilder: (_, __, ___) => const LoginScreen(),
transitionDuration: const Duration(milliseconds: 700),
transitionsBuilder: (_, animation, __, child) {
return FadeTransition(
opacity: animation,
child: SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, 0.05),
end: [Link],
).animate(animation),
child: child,
),
);
},
),
);
}
}
@override
void dispose() {
_ringController.dispose();
_fadeController.dispose();
_slideController.dispose();
[Link]();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: [Link],
body: Container(
decoration: const BoxDecoration(
gradient: RadialGradient(
center: [Link],
radius: 1.2,
colors: [
Color(0xFF0D1929),
Color(0xFF0A0E1A),
],
),
),
child: Stack(
children: [
// Decorative background grid
[Link](child: _buildGrid()),
// Main content
Center(
child: Column(
mainAxisAlignment: [Link],
children: [
// Animated logo
AnimatedBuilder(
animation: _ringAnimation,
builder: (context, child) {
return ScaleTransition(
scale: _scaleAnimation,
child: SizedBox(
width: 160,
height: 160,
child: CustomPaint(
painter: _LogoPainter(_ringAnimation.value),
child: Center(
child: Container(
width: 72,
height: 72,
decoration: BoxDecoration(
color: [Link](0.15),
shape: [Link],
border: [Link](
color: [Link](0.4),
width: 1.5,
),
),
child: const Icon(
Icons.fingerprint_rounded,
color: [Link],
size: 38,
),
),
),
),
),
);
},
),
const SizedBox(height: 40),
// App name
FadeTransition(
opacity: _fadeAnimation,
child: SlideTransition(
position: _slideAnimation,
child: Column(
children: [
const Text(
'PRESENCE',
style: TextStyle(
fontSize: 36,
fontWeight: FontWeight.w900,
color: [Link],
letterSpacing: 8,
),
),
const SizedBox(height: 8),
Text(
'Smart Attendance System',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w400,
color: [Link](0.8),
letterSpacing: 2,
),
),
const SizedBox(height: 48),
_buildLoadingDots(),
],
),
),
),
],
),
),
// Version at bottom
Positioned(
bottom: 40,
left: 0,
right: 0,
child: FadeTransition(
opacity: _fadeAnimation,
child: Text(
'v1.0.0',
textAlign: [Link],
style: TextStyle(
color: [Link](0.4),
fontSize: 12,
letterSpacing: 1.5,
),
),
),
),
],
),
),
);
}
Widget _buildGrid() {
return CustomPaint(painter: _GridPainter());
}
Widget _buildLoadingDots() {
return TweenAnimationBuilder<double>(
tween: Tween(begin: 0, end: 1),
duration: const Duration(seconds: 2),
builder: (context, value, _) {
return Row(
mainAxisSize: [Link],
children: [Link](3, (i) {
final delay = i / 3;
final opacity = [Link]((value - delay) * [Link]).clamp(0.0, 1.0);
return Padding(
padding: const [Link](horizontal: 4),
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
width: 8,
height: 8,
decoration: BoxDecoration(
shape: [Link],
color: [Link](opacity * 0.8 + 0.2),
),
),
);
}),
);
},
);
}
}
class _LogoPainter extends CustomPainter {
final double progress;
_LogoPainter([Link]);
@override
void paint(Canvas canvas, Size size) {
final center = Offset([Link] / 2, [Link] / 2);
// Outer ring
final outerPaint = Paint()
..color = [Link](0.25 * progress)
..style = [Link]
..strokeWidth = 1;
[Link](center, [Link] / 2 - 2, outerPaint);
// Animated arc
final arcPaint = Paint()
..color = [Link]
..style = [Link]
..strokeWidth = 2.5
..strokeCap = [Link];
[Link](
[Link](center: center, radius: [Link] / 2 - 2),
-[Link] / 2,
2 * [Link] * progress,
false,
arcPaint,
);
// Middle ring
final midPaint = Paint()
..color = [Link](0.15 * progress)
..style = [Link]
..strokeWidth = 1;
[Link](center, [Link] / 2 - 18, midPaint);
// Dot at arc end
if (progress > 0.05) {
final angle = -[Link] / 2 + 2 * [Link] * progress;
final dotPos = Offset(
[Link] + ([Link] / 2 - 2) * [Link](angle),
[Link] + ([Link] / 2 - 2) * [Link](angle),
);
final dotPaint = Paint()
..color = [Link]
..style = [Link];
[Link](dotPos, 5, dotPaint);
}
}
@override
bool shouldRepaint(_LogoPainter old) => [Link] != progress;
}
class _GridPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = const Color(0xFF1A2332).withOpacity(0.6)
..strokeWidth = 0.5;
const spacing = 40.0;
for (double x = 0; x < [Link]; x += spacing) {
[Link](Offset(x, 0), Offset(x, [Link]), paint);
}
for (double y = 0; y < [Link]; y += spacing) {
[Link](Offset(0, y), Offset([Link], y), paint);
}
}
@override
bool shouldRepaint(_GridPainter old) => false;
}