174 lines
4.8 KiB
Dart
174 lines
4.8 KiB
Dart
import 'dart:math';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import '../gen/assets.gen.dart';
|
|
|
|
class CoolSplashScreen extends StatefulWidget {
|
|
final Widget nextScreen;
|
|
final Duration duration;
|
|
|
|
const CoolSplashScreen({
|
|
super.key,
|
|
required this.nextScreen,
|
|
this.duration = const Duration(seconds: 6),
|
|
});
|
|
|
|
@override
|
|
State<CoolSplashScreen> createState() => _CoolSplashScreenState();
|
|
}
|
|
|
|
class _CoolSplashScreenState extends State<CoolSplashScreen>
|
|
with TickerProviderStateMixin {
|
|
late AnimationController _mainController;
|
|
late Animation<double> _backgroundAnimation;
|
|
late Animation<double> _particlesAnimation;
|
|
late Animation<double> _logoAnimation;
|
|
late Animation<double> _textAnimation;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
_mainController = AnimationController(
|
|
duration: const Duration(milliseconds: 4000),
|
|
vsync: this,
|
|
);
|
|
|
|
_backgroundAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
CurvedAnimation(
|
|
parent: _mainController,
|
|
curve: const Interval(0.0, 0.5, curve: Curves.easeInOut),
|
|
),
|
|
);
|
|
|
|
_particlesAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
CurvedAnimation(
|
|
parent: _mainController,
|
|
curve: const Interval(0.2, 0.7, curve: Curves.easeOut),
|
|
),
|
|
);
|
|
|
|
_logoAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
CurvedAnimation(
|
|
parent: _mainController,
|
|
curve: const Interval(0.5, 0.9, curve: Curves.elasticOut),
|
|
),
|
|
);
|
|
|
|
_textAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
|
|
CurvedAnimation(
|
|
parent: _mainController,
|
|
curve: const Interval(0.7, 1.0, curve: Curves.easeOut),
|
|
),
|
|
);
|
|
|
|
_mainController.forward();
|
|
|
|
Future.delayed(widget.duration, () {
|
|
if (mounted) {
|
|
Navigator.of(context).pushReplacement(
|
|
PageRouteBuilder(
|
|
pageBuilder: (_, __, ___) => widget.nextScreen,
|
|
transitionDuration: const Duration(milliseconds: 700),
|
|
transitionsBuilder: (_, animation, __, child) {
|
|
return FadeTransition(opacity: animation, child: child);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_mainController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: AnimatedBuilder(
|
|
animation: _mainController,
|
|
builder: (context, child) {
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
gradient: LinearGradient(
|
|
begin: Alignment.topLeft,
|
|
end: Alignment.bottomRight,
|
|
colors: [
|
|
Color.lerp(const Color(0xFFF5F5F5), const Color(0xFFE0E0E0), _backgroundAnimation.value)!,
|
|
Color.lerp(const Color(0xFFFFFFFF), const Color(0xFFF5F5F5), _backgroundAnimation.value)!,
|
|
],
|
|
),
|
|
),
|
|
child: Stack(
|
|
children: [
|
|
for (int i = 0; i < 30; i++)
|
|
Particle(
|
|
animation: _particlesAnimation,
|
|
size: Random().nextDouble() * 5 + 2,
|
|
color: Colors.blueGrey.withOpacity(Random().nextDouble() * 0.3 + 0.1),
|
|
alignment: Alignment(
|
|
(Random().nextDouble() * 2 - 1) * (2 - _particlesAnimation.value),
|
|
(Random().nextDouble() * 2 - 1) * (2 - _particlesAnimation.value),
|
|
),
|
|
),
|
|
|
|
Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Transform.scale(
|
|
scale: _logoAnimation.value,
|
|
child: SvgPicture.asset(
|
|
Assets.images.logo.path,
|
|
height: 140,
|
|
width: 140,
|
|
),
|
|
),
|
|
const SizedBox(height: 30),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class Particle extends StatelessWidget {
|
|
final Animation<double> animation;
|
|
final double size;
|
|
final Color color;
|
|
final Alignment alignment;
|
|
|
|
const Particle({
|
|
super.key,
|
|
required this.animation,
|
|
required this.size,
|
|
required this.color,
|
|
required this.alignment,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Align(
|
|
alignment: alignment,
|
|
child: Opacity(
|
|
opacity: animation.value,
|
|
child: Container(
|
|
width: size,
|
|
height: size,
|
|
decoration: BoxDecoration(
|
|
color: color,
|
|
shape: BoxShape.circle,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |