import 'package:flutter/material.dart'; import '../../../../core/animations/animated_button.dart'; import '../../../../core/animations/animated_notifications.dart'; import '../../../../core/animations/page_transitions.dart'; import '../../../../shared/theme/app_theme.dart'; /// Page de démonstration des animations class AnimationsDemoPage extends StatefulWidget { const AnimationsDemoPage({super.key}); @override State createState() => _AnimationsDemoPageState(); } class _AnimationsDemoPageState extends State with TickerProviderStateMixin { late AnimationController _floatingController; late AnimationController _pulseController; late Animation _floatingAnimation; late Animation _pulseAnimation; @override void initState() { super.initState(); _floatingController = AnimationController( duration: const Duration(seconds: 2), vsync: this, )..repeat(reverse: true); _pulseController = AnimationController( duration: const Duration(milliseconds: 1500), vsync: this, )..repeat(); _floatingAnimation = Tween( begin: -10.0, end: 10.0, ).animate(CurvedAnimation( parent: _floatingController, curve: Curves.easeInOut, )); _pulseAnimation = Tween( begin: 1.0, end: 1.2, ).animate(CurvedAnimation( parent: _pulseController, curve: Curves.elasticOut, )); } @override void dispose() { _floatingController.dispose(); _pulseController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Démonstration des Animations'), backgroundColor: AppTheme.primaryColor, foregroundColor: Colors.white, elevation: 0, ), body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Section Boutons Animés _buildSection( 'Boutons Animés', [ const SizedBox(height: 16), AnimatedButton( text: 'Bouton Principal', onPressed: () => _showNotification(NotificationType.success), style: AnimatedButtonStyle.primary, ), const SizedBox(height: 12), AnimatedButton( text: 'Bouton Secondaire', onPressed: () => _showNotification(NotificationType.info), style: AnimatedButtonStyle.secondary, ), const SizedBox(height: 12), AnimatedButton( text: 'Bouton de Succès', onPressed: () => _showNotification(NotificationType.success), style: AnimatedButtonStyle.success, ), const SizedBox(height: 12), AnimatedButton( text: 'Bouton d\'Avertissement', onPressed: () => _showNotification(NotificationType.warning), style: AnimatedButtonStyle.warning, ), const SizedBox(height: 12), AnimatedButton( text: 'Bouton d\'Erreur', onPressed: () => _showNotification(NotificationType.error), style: AnimatedButtonStyle.error, ), const SizedBox(height: 12), AnimatedButton( text: 'Bouton Contour', onPressed: () => _showNotification(NotificationType.info), style: AnimatedButtonStyle.outline, ), ], ), const SizedBox(height: 32), // Section Notifications _buildSection( 'Notifications Animées', [ const SizedBox(height: 16), Row( children: [ Expanded( child: ElevatedButton.icon( onPressed: () => _showNotification(NotificationType.success), icon: const Icon(Icons.check_circle), label: const Text('Succès'), style: ElevatedButton.styleFrom( backgroundColor: AppTheme.successColor, foregroundColor: Colors.white, ), ), ), const SizedBox(width: 8), Expanded( child: ElevatedButton.icon( onPressed: () => _showNotification(NotificationType.error), icon: const Icon(Icons.error), label: const Text('Erreur'), style: ElevatedButton.styleFrom( backgroundColor: AppTheme.errorColor, foregroundColor: Colors.white, ), ), ), ], ), const SizedBox(height: 8), Row( children: [ Expanded( child: ElevatedButton.icon( onPressed: () => _showNotification(NotificationType.warning), icon: const Icon(Icons.warning), label: const Text('Avertissement'), style: ElevatedButton.styleFrom( backgroundColor: AppTheme.warningColor, foregroundColor: Colors.white, ), ), ), const SizedBox(width: 8), Expanded( child: ElevatedButton.icon( onPressed: () => _showNotification(NotificationType.info), icon: const Icon(Icons.info), label: const Text('Information'), style: ElevatedButton.styleFrom( backgroundColor: AppTheme.primaryColor, foregroundColor: Colors.white, ), ), ), ], ), ], ), const SizedBox(height: 32), // Section Transitions de Page _buildSection( 'Transitions de Page', [ const SizedBox(height: 16), _buildTransitionButton( 'Glissement depuis la droite', () => _navigateWithTransition(PageTransitions.slideFromRight), ), const SizedBox(height: 8), _buildTransitionButton( 'Glissement depuis le bas', () => _navigateWithTransition(PageTransitions.slideFromBottom), ), const SizedBox(height: 8), _buildTransitionButton( 'Fondu', () => _navigateWithTransition(PageTransitions.fadeIn), ), const SizedBox(height: 8), _buildTransitionButton( 'Échelle avec fondu', () => _navigateWithTransition(PageTransitions.scaleWithFade), ), const SizedBox(height: 8), _buildTransitionButton( 'Rebond', () => _navigateWithTransition(PageTransitions.bounceIn), ), const SizedBox(height: 8), _buildTransitionButton( 'Parallaxe', () => _navigateWithTransition(PageTransitions.slideWithParallax), ), const SizedBox(height: 8), _buildTransitionButton( 'Morphing avec Blur', () => _navigateWithTransition(PageTransitions.morphWithBlur), ), const SizedBox(height: 8), _buildTransitionButton( 'Rotation 3D', () => _navigateWithTransition(PageTransitions.rotate3D), ), ], ), const SizedBox(height: 32), // Section Animations Continues _buildSection( 'Animations Continues', [ const SizedBox(height: 16), Center( child: Column( children: [ AnimatedBuilder( animation: _floatingAnimation, builder: (context, child) { return Transform.translate( offset: Offset(0, _floatingAnimation.value), child: Container( width: 80, height: 80, decoration: BoxDecoration( gradient: LinearGradient( colors: [ AppTheme.primaryColor, AppTheme.primaryColor.withOpacity(0.7), ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(40), boxShadow: [ BoxShadow( color: AppTheme.primaryColor.withOpacity(0.3), blurRadius: 12, offset: const Offset(0, 4), ), ], ), child: const Icon( Icons.star, color: Colors.white, size: 40, ), ), ); }, ), const SizedBox(height: 16), const Text( 'Animation Flottante', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 32), AnimatedBuilder( animation: _pulseAnimation, builder: (context, child) { return Transform.scale( scale: _pulseAnimation.value, child: Container( width: 60, height: 60, decoration: BoxDecoration( color: AppTheme.successColor, borderRadius: BorderRadius.circular(30), boxShadow: [ BoxShadow( color: AppTheme.successColor.withOpacity(0.4), blurRadius: 20, spreadRadius: 5, ), ], ), child: const Icon( Icons.favorite, color: Colors.white, size: 30, ), ), ); }, ), const SizedBox(height: 16), const Text( 'Animation Pulsante', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), ], ), ), ], ), const SizedBox(height: 32), ], ), ), ); } Widget _buildSection(String title, List children) { return Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), child: Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: AppTheme.primaryColor, ), ), const Divider(height: 24), ...children, ], ), ), ); } Widget _buildTransitionButton(String text, VoidCallback onPressed) { return SizedBox( width: double.infinity, child: OutlinedButton( onPressed: onPressed, style: OutlinedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 12), side: const BorderSide(color: AppTheme.primaryColor), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: Text( text, style: const TextStyle( color: AppTheme.primaryColor, fontWeight: FontWeight.w600, ), ), ), ); } void _showNotification(NotificationType type) { switch (type) { case NotificationType.success: AnimatedNotifications.showSuccess( context, 'Opération réussie avec succès !', ); break; case NotificationType.error: AnimatedNotifications.showError( context, 'Une erreur s\'est produite lors de l\'opération.', ); break; case NotificationType.warning: AnimatedNotifications.showWarning( context, 'Attention : cette action nécessite une confirmation.', ); break; case NotificationType.info: AnimatedNotifications.showInfo( context, 'Information : les données ont été mises à jour.', ); break; } } void _navigateWithTransition(PageRouteBuilder Function(Widget) transitionBuilder) { Navigator.of(context).push( transitionBuilder(const _DemoDestinationPage()), ); } } /// Page de destination pour les démonstrations de transition class _DemoDestinationPage extends StatelessWidget { const _DemoDestinationPage(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Page de Destination'), backgroundColor: AppTheme.secondaryColor, foregroundColor: Colors.white, ), body: const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.check_circle, size: 80, color: AppTheme.successColor, ), SizedBox(height: 24), Text( 'Transition réussie !', style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: AppTheme.primaryColor, ), ), SizedBox(height: 16), Text( 'Vous pouvez revenir en arrière\npour tester d\'autres transitions.', textAlign: TextAlign.center, style: TextStyle( fontSize: 16, color: Colors.grey, ), ), ], ), ), ); } }