import 'package:flutter/material.dart'; class AppAnimations { const AppAnimations._(); /// A standard fade transition static Widget fade({ required Widget child, Duration duration = const Duration(milliseconds: 300), }) { return AnimatedSwitcher( duration: duration, child: child, ); } /// A slide transition from the bottom (Brutalist style) static Widget slideIn({ required Widget child, Offset begin = const Offset(0, 0.1), Duration duration = const Duration(milliseconds: 400), }) { return TweenAnimationBuilder( tween: Tween(begin: begin, end: Offset.zero), duration: duration, curve: Curves.easeOutQuart, builder: (context, offset, child) { return FractionalTranslation( translation: offset, child: child, ); }, child: child, ); } /// A simple "Glitch" effect using staggered offsets and opacities /// This simulates an underground/grunge signal interference. static Widget glitch({required Widget child}) { return _GlitchWidget(child: child); } } class _GlitchWidget extends StatefulWidget { final Widget child; const _GlitchWidget({required this.child}); @override State<_GlitchWidget> createState() => _GlitchWidgetState(); } class _GlitchWidgetState extends State<_GlitchWidget> with SingleTickerProviderStateMixin { late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 500), )..repeat(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (context, child) { final double glitchFactor = _controller.value; // Only glitch occasionally if (glitchFactor > 0.9) { return Stack( children: [ Transform.translate( offset: const Offset(2, 0), child: Opacity(opacity: 0.5, child: widget.child), ), Transform.translate( offset: const Offset(-2, 1), child: Opacity(opacity: 0.5, child: widget.child), ), widget.child, ], ); } return widget.child; }, ); } }