0

I am implementing waveform visualization for mic in my app.

class BarVisualizer extends CustomPainter {
  final List<double> waveData;
BarVisualizer({
    required this.waveData,
});
 @override
  void paint(Canvas canvas, Size size) {
    for (var i = 0; i < waveData.length; i++) {
    canvas.drawLine(Offset(i.toDouble() + i  , 0),
          Offset(i.toDouble() +  i, -waveData[i]), wavePaint);     
    }
  }
@override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }

above for-loop draws lines for each decibel value I get from mic. As I am using a mic to get data, the list of decibel will get large and it start painting outside of the screen.

So my question is how can I move the previously painted lines back to paint new incoming decibel values inside the screen?

Pokaboom
  • 1,110
  • 9
  • 28
  • 1
    You need to determine which at which length of the list it starts drawing offscreen and at that point remove first element from `waveData` each time you adding new one – Dmytro Rostopira Jan 28 '22 at 15:16

2 Answers2

0

Use the canvas.translate method to move the canvas surface around, so that your draw calls can always be within the screen bounds. You will need to also change your drawLine calls to accommodate for how the canvas has moved.

Patrick Allwood
  • 1,822
  • 17
  • 21
0

what I did was created a callback when a certain condition matches and call the setState from that call back to the offset which looks like this,

for (var i = 0; i < waveData.length; i++) {
if ((spacing * i) + offset.dx > size.width * sizeCounter) {
          callback();
        }
        canvas.drawLine(
            Offset(-scrollOffset.dx + offset.dx + (spacing * i), 100),
            Offset(-scrollOffset.dx + offset.dx + (spacing * i),
                -waveData[i] + 100),
            wavePaint);
      }

now in the UI,

CustomPaint(
     painter: Barpainter(
              callback:(){
                WidgetsBinding.instance!.addPostFrameCallback(
                                  (timeStamp) {
                                setState(
                                      () {
                                    scrollOffset +=  Offset(width, 0);
                                    sizeCounter++;
                                  },
                                );
                              },
                            );
       }
  )
)

this add extra offset when it reaches end of the screen

Pokaboom
  • 1,110
  • 9
  • 28