preface

Recently, flutter Custompaint was used to create a wave effect that fluctuates with sound. Let’s take you to realize this wave effect and share the process and ideas

The realization of curve drawing

Regardless of whether the native Flutter, or the front-end, the curve drawing is implemented similarly on different platforms. By determining the position coordinates of different points (x1, y1) (x2,y2)… And then use Bezier curve or system method to fit the curve between two points, and finally give the curve path to the canvas to draw, so that the curve comes out

episode

  • The end result is a curve with 0 amplitude at the beginning and end and increasing towards the middle
  • Let’s start with the basics, let’s draw a curve with the same amplitude, and it fluctuates.
  • Write code incrementally, step by step…

This simple!

  • Draw a corrugated curve twice the width of container View

  • Repeat the slide from left to right, and the visual effect is a wavy curve

    After that, the designer said that the above one was lazy and gave the wrong picture, what was in his mind at that time

To calm the nerves, let’s share curves with the same amplitude and those with different amplitudes

Draw curves of the same amplitude

class VoiceWavePainter extends CustomPainter {
  @override
  voidpaint(Canvas canvas, Size size) { Paint paint = Paint() .. color = Colors.red .. style = PaintingStyle.stroke .. strokeWidth =2;
    Path path = Path();
    // 
    path.quadraticBezierTo(50.- 80..100.0);
    path.quadraticBezierTo(150.80.200.0);

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(VoiceWavePainter oldDelegate) => false;
}
Copy the code


The path. QuadraticBezierTo defines positions P1 and P2 A sinusoidal curve is drawn, with P0 being the starting point of the path

path.quadraticBezierTo(50, -80, 100, 0); P0 (0,0) P1 (50,-80) p2 (100,0) path. QuadraticBezierTo (150, 80, 200, 0); P0 (100,0) P1 (150,80) p2 (200,0)Copy the code

And so on, the desired sinusoid

A curve of the same amplitude

The principle has been said that it is no longer repeated, and the diagram is more intuitive. If the left slide is repeated, the waveform on the left and right sides of the rectangular frame starts and ends exactly the same, and the visual effect will produce the effect of curve fluctuation all the time

Finally realize

  @override
  void paint(Canvas canvas, Size size) {
    int waveNum = 4;
    double waveWidth = this.painterWidth / waveNum;
    
    canvas.clipRect((Rect.fromCenter(
        center: Offset(0, size.height / 2),
        width: painterWidth * 2,
        height: 120)));
    canvas.translate(0, size.height / 2); Paint paint = Paint() .. color = Colors.red .. style = PaintingStyle.stroke .. strokeWidth =2;

    Path path = Path();
   
    for (var i = 0; i < waveNum * 2; i++) {
      path.quadraticBezierTo(waveWidth / 2 + waveWidth * i,
          waveHeight * (i.isOdd ? 1 : - 1), waveWidth * (i + 1), 0);
    }
    canvas.translate(-painterWidth * repaint.value, 0); canvas.drawPath(path, paint); }}Copy the code
  class _VoiceWaveState extends State<VoiceWave>
    with SingleTickerProviderStateMixin {
  AnimationController _waveController;
  @override
  void initState() {
    _waveController =
        AnimationController(vsync: this, duration: Duration(seconds: 1)).. repeat(); }@override
  void dispose() {
    _waveController.dispose();
    super.dispose();
  }
Copy the code
  • defineAnimationControllerAnd pass in a customCustomPainter
  • painterWidthLength of curvewaveNumThe number of visible fluctuations
  • waveWidth = this.painterWidth / waveNum.waveWidthHalf a wavelength
    for (var i = 0; i < waveNum * 2; i++) {
       path.quadraticBezierTo(waveWidth / 2 + waveWidth * i,
          waveHeight * (i.isOdd ? 1 : - 1), waveWidth * (i + 1), 0);
    }
Copy the code
  • The position of point is defined by cycle. If we want to see the curve of the length of 4 upper and lower peaks, we need to draw the curve of the upper and lower peaks of 8, a total of 16 coordinate points. After simplification, the position of the point is determined by cycle
  • throughcanvas.translate(-painterWidth * repaint.value, 0)Implement repeated movement of canvas

conclusion

  • advantages
    • Can quickly achieve the effect of curve fluctuation
  • disadvantages
    • The number of fluctuations must be an even multiple of the complete sinusoidal period. In odd case, the start of the repeated animation is opposite to the y value of the odd point, and there is no coherent dynamic effect
    • Gradient effect cannot be used

Next section Flutter CustomPaint Drawing Sound Wave Curve (2)

Reprint without authorisation is prohibited