1

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

DolDurma
  • 15,753
  • 51
  • 198
  • 377

2 Answers2

1

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.

Yashawant
  • 1,122
  • 4
  • 10
0

I would ditch path_0 and simply rescale path:

Paint paint_0_fill = Paint()
      ..style = PaintingStyle.fill
      ..color = color;

final scalingfactor_w = size.width/50; //original svg size seemed to be 50
final scalingfactor_h = size.height/50; //original svg size seemed to be 50

var scalingMatrix =
        Float64List.fromList([scalingfactor_w, 0, 0, 0, 0, scalingfactor_h, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);

path = path.transform(scalingMatrix);

canvas.drawPath(path, paint_0_fill);

this isnt a perfect fit if the appbar should start at the top but it should hint you in the right direction without needing to recode the whole path (the transform matrix should also allow translation)

otherwise you might simply skip this and use flutter_svg

HannesH
  • 932
  • 2
  • 12