Flutter Creating Custom Curve Shape Using Custom Clipper

flutter-custom-clipper

Welcome back guys, In this post I’m going to show you how to use Custom Clipper to create custom shapes to create stunning UI.

We will use Flutter ClipPath Widget to create custom shapes, Flutter also have ClipRect, ClipRRect and ClipOval Widgets that help us to create custom shapes, but these widgets are limited to some shapes. By using ClipPath Widget we can make lot of custom shapes.

ClipPath

This widget use to create custom shaped widgets, this has clipper property that we have to provide custom clipper to work. We are going to create below shape using custom clipper.

First we need to create a Container and wrap it with ClipPath Widget.

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Column(
      children: [
        ClipPath(
            clipper: MyClipper(),
            child: Container(
              width: double.infinity,
              height: 350.0,
              color: Color(0XFF2DBB54),
            ),
        ]
      ),
    ),
  );
}

As i said earlier ClipPath widget require clipper property, to provide clipper property we need to create a class that extends CustomClipper<Path> and must override two methods.

class MyClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path = Path();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return false;
  }
}

The getClip method is called whenever the custom clip needs to be updated and this method has a Size parameter that gives widget Width and Height.

The shouldReclip method is called whenever a new instance of the custom clipper delegate class is provided to the clip object, if the new instance contains new information than the old instance, the method should return true, otherwise it should return false.

Let’s see how we can draw the path, to draw the we use (x, y) coordinates, where x represents horizontal axis and y represents vertical axis. Always drawing path starts from top left corner which is (0,0)

Flutter Clipper

Flutter Path has few methods to create custom shapes, in this article we use lineTo and quadraticBezierTo.

lineTo – This method is used to draw line segment from current point to given point.

quadraticBezierTo – This method is used to draw quadratic bezier curves.

Let’s draw our custom shape on our app, modify the getClip method as below

class MyClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path = Path();

    path.lineTo(0, size.height - 150);
    path.quadraticBezierTo(size.width / 2, size.height, size.width, size.height - 170);
    path.lineTo(size.width, 0);
    path.close();

    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return false;
  }
}

As you can see, first we have used lineTo method to draw a line from x=0 to y=size.height – 150, since size.height = 350 our line end point is 200.

Then we are using quadraticBezierTo method to create the curve we want in the bottom of our container. We have to provide four arguments to quadraticBezierTo method.

quadraticBezierTo(double controlPoint.dx, double controlPoint.dy, double endPoint.dx, double endPoint.dy) – These are the four arguments we should provide.

From Wikipedia
From WIkipedia

As you can see in above pictures, p0 is the starting point, p1 is the control point that we define in first two arguments. p2 is the end point that we defining in last two arguments. In our use case we used below arguments to quadraticBezierTo method.

path.quadraticBezierTo(size.width / 2, size.height, size.width, size.height - 170);

Our starting point is (x=0, y=200) and our control point is in (x=size.width/2, y=350)(350 is height of the container), finally our end point is (x=size.width, y=350-170).

As you can see above picture we can get curve between starting point and end point using control point.

Finally we drawing another line from x=size.width to y=0 and closing the path by path.close() calling close() method. Our final result will be like below.

If you want source files you can get them from here.

I have made video tutorial too, watch it on our YouTube channel.