In the below code i need to show the wave form when the user speaks, but i'm not sure about the code, it does't gets me positive
Reference image Expected Output
Also it needs to be varies based on the amplitude change and color of the wave also to be changed based on the resultant amplitude
///
class Waveform extends StatelessWidget {
final List<double> amplitudes;
const Waveform(this.amplitudes, {super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 100.0,
child: CustomPaint(
painter: WaveformPainter(amplitudes),
),
);
}
}
///
class WaveformPainter extends CustomPainter {
final List<double> amplitudes;
WaveformPainter(this.amplitudes);
@override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()
..color = Colors.blue
..strokeCap = StrokeCap.round
..strokeWidth = 4.0;
final Path path = Path();
for (int i = 0; i < amplitudes.length; i++) {
final double x = i * size.width / (amplitudes.length - 1);
final double y = (1 - amplitudes[i]) * size.height / 2;
if (i == 0) {
path.moveTo(x, y);
} else {
path.lineTo(x, y);
}
}
// Adding gradient
paint.shader = LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.blue.withOpacity(0.5),
Colors.blue.withOpacity(0.0),
],
).createShader(Rect.fromPoints(Offset(0, 0), Offset(0, size.height)));
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
Your approach looks good but I assume it results in sharp lines instead of smooth curves at peaks. One way to achieve the smooth wave is by using the CatmullRomSpline. For this, you will need at least 4 values in your input list of amplitues. If you don't have 4 points you will have to generate them.