visualizer.dart 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import 'package:flutter/material.dart';
  2. import 'dart:math';
  3. /// A widget that displays a visualizer animation.
  4. ///
  5. /// The visualizer animates more vigorously when [isTalking] is `true`.
  6. class Visualizer extends StatefulWidget {
  7. /// Whether the visualizer should animate vigorously.
  8. final bool isTalking;
  9. const Visualizer({super.key, this.isTalking = false});
  10. @override
  11. State<Visualizer> createState() => _VisualizerState();
  12. }
  13. class _VisualizerState extends State<Visualizer>
  14. with SingleTickerProviderStateMixin {
  15. late AnimationController _controller;
  16. @override
  17. void initState() {
  18. super.initState();
  19. _controller = AnimationController(
  20. vsync: this,
  21. duration: const Duration(milliseconds: 1000),
  22. )..repeat();
  23. }
  24. @override
  25. void dispose() {
  26. _controller.dispose();
  27. super.dispose();
  28. }
  29. @override
  30. Widget build(BuildContext context) {
  31. return SizedBox(
  32. height: 100,
  33. width: double.infinity,
  34. child: AnimatedBuilder(
  35. animation: _controller,
  36. builder: (context, child) {
  37. return Row(
  38. mainAxisAlignment: MainAxisAlignment.center,
  39. children: List.generate(5, (index) {
  40. final double baseHeight = widget.isTalking ? 60 : 10;
  41. final double minHeight = widget.isTalking ? 20 : 10;
  42. final height =
  43. minHeight +
  44. baseHeight *
  45. (0.5 + 0.5 * sin(_controller.value * 2 * pi + index));
  46. return Container(
  47. margin: const EdgeInsets.symmetric(horizontal: 4),
  48. width: 10,
  49. height: height,
  50. decoration: BoxDecoration(
  51. color: const Color(0xFFA8C7FA),
  52. borderRadius: BorderRadius.circular(5),
  53. boxShadow: [
  54. BoxShadow(
  55. color: const Color(0xFFA8C7FA).withAlpha(127),
  56. blurRadius: 10,
  57. spreadRadius: 2,
  58. ),
  59. ],
  60. ),
  61. );
  62. }),
  63. );
  64. },
  65. ),
  66. );
  67. }
  68. }