flutterdartflutter-custompainter

Flutter programing svg design


I designed a simple svg into this website and i'll to try programing that in flutter

enter image description here

I have implemented the code using this approach:

class AppbarBackgroundPainter extends CustomPainter {
  final Color color;

  AppbarBackgroundPainter(this.color);

  @override
  void paint(Canvas canvas, Size size) {
    final Paint paint = Paint()
      ..color = color
      ..style = PaintingStyle.fill;

    /*Path path = Path()
      ..moveTo(1, 50)
      ..moveTo(0, 33)
      ..lineTo(0, 41)
      ..quadraticBezierTo(0, 40, 1, 40)
      ..lineTo(24, 40)
      ..cubicTo(27, 40, 27, 40, 29, 36)
      ..quadraticBezierTo(30, 34, 32, 34)
      ..lineTo(54, 34)
      ..lineTo(54, 33)
      ..lineTo(0, 33);*/

    /* converted SVG to dart*/
    Path path_0 = Path();

    path_0.moveTo(0, size.height);
    path_0.lineTo(0, size.height);
    path_0.cubicTo(
        0,
        size.height * 0.9207522,
        size.width * 0.006172833,
        size.height * 0.8837156,
        size.width * 0.01851852,
        size.height * 0.8837156);
    path_0.lineTo(size.width * 0.4444444, size.height * 0.8837156);
    path_0.cubicTo(
        size.width * 0.5000000,
        size.height * 0.8837156,
        size.width * 0.5000000,
        size.height * 0.8837156,
        size.width * 0.5370370,
        size.height * 0.4392711);
    path_0.cubicTo(
        size.width * 0.5493833,
        size.height * 0.2911222,
        size.width * 0.5679019,
        size.height * 0.2170489,
        size.width * 0.5925926,
        size.height * 0.2170489);
    path_0.lineTo(size.width, size.height * 0.2170489);
    path_0.lineTo(size.width, 0);
    path_0.lineTo(0, 0);
    path_0.close();

    Paint paint_0_fill = Paint()..style = PaintingStyle.fill;
    paint_0_fill.color = color;
    canvas.drawPath(path_0, paint_0_fill);

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

However, I was unable to apply the things shown in the picture to the code. it should be used on appbar background


Solution

  • You can add custom Border to AppBar by overriding ContinuousRectangleBorder and setting it as shape property of AppBar

    you can create custom border like this:

    class CustomAppBarShape extends ContinuousRectangleBorder {
      @override
      Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
        double height = rect.height; // you can add different height here
        double width = rect.width;
        var path = Path();
        path.lineTo(0, height + width * 0.02);
        path.arcToPoint(
          Offset(width * 0.02, height),
          radius: Radius.circular(width * 0.02),
        );
        path.lineTo(width * 0.6, height);
        path.cubicTo(
          width * 0.66,
          height,
          width * 0.64,
          height * 0.2,
          width * 0.7,
          height * 0.2,
        );
    
        path.lineTo(width, height * 0.2);
        path.lineTo(width, 0);
        path.close();
    
        return path;
      }
    }
    

    Then you can pass it to shape of AppBar like this

    AppBar(
      title: Text(widget.title),
      shape: CustomAppBarShape(),
    )
    

    the result will be something like this,

    result

    I have added approximate path based on image you provided, you can edit the path so that it is similar to the path in the code you provided, but instead of CustomPainter you can set custom border by setting the shape value of AppBar.

    you can see live example here.

    Edit:

    To customize the left side width you can pass the width percentage or fraction as an argument to CustomAppBarShape constructor.

    class CustomAppBarShape extends ContinuousRectangleBorder {
      
      final double leftWidthVal;
      
      const CustomAppBarShape({this.leftWidthVal = 0.5});
      
      @override
      Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
        double height = rect.height; // you can add different height here
        double width = rect.width;
        var path = Path();
        path.lineTo(0, height + width * 0.02);
        path.arcToPoint(
          Offset(width * 0.02, height),
          radius: Radius.circular(width * 0.02),
        );
        path.lineTo(width * leftWidthVal, height);
        path.cubicTo(
          width * (leftWidthVal + 0.06),
          height,
          width * (leftWidthVal + 0.04),
          height * 0.2,
          width * (leftWidthVal + 0.1),
          height * 0.2,
        );
    
        path.lineTo(width, height * 0.2);
        path.lineTo(width, 0);
        path.close();
    
        return path;
      }
    }
    

    and set the leftWidthVal value,

    AppBar(
      title: Text(widget.title),
      shape: const CustomAppBarShape(leftWidthVal: 0.1),
    )
    

    if you set the value 0.1 or 10% result will be like this,

    enter image description here

    I have also updates the live example on dartpad.