Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to match this curved profile banner shape?

I’m trying to replicate a custom curved profile banner shape using CustomPaint in Flutter.

This is the desired shape I’m trying to achieve — notice how the bottom of the banner has a smooth inward curve (concave) with nice rounded edges:

enter image description here

However, here’s the shape I’m currently getting — the curve doesn’t match, and the corners are not blending correctly:

enter image description here

and this is my current code

My Current Code

What I need help with: How to match the exact smooth bottom curve of the profile banner as shown in the first image.

Ensuring the edges curve correctly and symmetrically from left to right.

I’m open to using cubicTo, quadraticBezierTo, or even arcToPoint — whichever helps match the reference shape.

Would really appreciate any pointers on fixing the Path logic.

like image 717
Akashptl Avatar asked Aug 31 '25 04:08

Akashptl


1 Answers

I used CustomClipper and achieved the same output as shown in your image. Try the code below.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          color: Colors.black,
          height: 300,
          width: 400,
          child: Stack(
            alignment: Alignment.topCenter,
            children: [
              ClipPath(
                clipper: WaveClipper(),
                child: Container(width: 400, height: 300, color: Colors.red),
              ),

              Positioned(
                bottom: 15,
                child: Container(
                  height: 130,
                  width: 130,
                  decoration: BoxDecoration(
                    color: Colors.green,
                    shape: BoxShape.circle,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

class WaveClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    double waveHeight = 100;
    double waveWidth = 65;
    double blackHeight = 90;
    double cornerCurve = 40;

    final path = Path();
    path.moveTo(0, 0);
    path.lineTo(0, size.height - blackHeight);

    path.quadraticBezierTo(
      (size.width / 2) - waveWidth - cornerCurve,
      size.height - blackHeight,
      (size.width / 2) - waveWidth,
      size.height - blackHeight - cornerCurve,
    );

    path.quadraticBezierTo(
      size.width / 2,
      size.height - blackHeight - waveHeight,
      (size.width / 2) + waveWidth,
      size.height - blackHeight - cornerCurve,
    );

    path.quadraticBezierTo(
      (size.width / 2) + waveWidth + cornerCurve,
      size.height - blackHeight,
      size.width,
      size.height - blackHeight,
    );
    path.lineTo(size.width, 0);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
like image 116
DroidFlutter Avatar answered Sep 02 '25 19:09

DroidFlutter