| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- import 'dart:math' as math;
- import 'package:flutter/material.dart';
- import '../../../core/theme/app_colors.dart';
- /// A tiny decorative equalizer shown while media audio is active. It is not a
- /// real analyser; the bars are phased sine waves.
- class MusicEqualizer extends StatefulWidget {
- const MusicEqualizer({super.key, this.compact = false});
- final bool compact;
- @override
- State<MusicEqualizer> createState() => _MusicEqualizerState();
- }
- class _MusicEqualizerState extends State<MusicEqualizer>
- with SingleTickerProviderStateMixin {
- late final AnimationController _controller;
- @override
- void initState() {
- super.initState();
- _controller = AnimationController(
- vsync: this,
- duration: const Duration(milliseconds: 900),
- )..repeat();
- }
- @override
- void dispose() {
- _controller.dispose();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- final colors = context.colors;
- final width = widget.compact ? 24.0 : 30.0;
- final height = widget.compact ? 14.0 : 16.0;
- final minBar = widget.compact ? 3.0 : 3.5;
- final maxBar = widget.compact ? 7.0 : 8.0;
- const phases = <double>[0.0, 2.1, 4.2];
- return Semantics(
- label: 'Music playing',
- child: Container(
- width: width,
- height: height,
- padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
- decoration: BoxDecoration(
- color: colors.surface.withValues(alpha: 0.9),
- borderRadius: BorderRadius.circular(6),
- border: Border.all(color: colors.border, width: 0.6),
- ),
- child: AnimatedBuilder(
- animation: _controller,
- builder: (context, _) {
- final phase = _controller.value * 2 * math.pi;
- return Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- for (final offset in phases)
- SizedBox(
- width: 2.2,
- height:
- minBar +
- (maxBar - minBar) *
- ((math.sin(phase + offset) + 1) / 2),
- child: DecoratedBox(
- decoration: BoxDecoration(
- color: colors.accent,
- borderRadius: BorderRadius.circular(2),
- ),
- ),
- ),
- ],
- );
- },
- ),
- ),
- );
- }
- }
|