Flutter - Using Clipper (ClipOval, ClipRect, ClipRRect, ClipPath)

This tutorial provides some examples of how to use clipper in Flutter including how to use built-in clippers and how to create CustomClipper.

Sometimes you may want to clip a Widget using certain clipper. In Flutter, it can be done easily thanks to built-in clippers such as ClipOval, ClipRect, ClipRRect, and ClipPath. However, if you want to clip a Widget using your own custom clipper, it's also possible by creating a class that extends CustomClipper.

ClipOval

It clips the child using an oval. If clipper is null, the create oval will use the widget's bounding box. Therefore, changing the size of the widget also changes the oval size. If the width and height of the widget are equal, the shape will be a circle.

  child: ClipOval(
    child: Image.network(
      'https://i.ibb.co/1vXpqVs/flutter-logo.jpg',
    ),
  ),

Here's the result.

Flutter ClipOval

ClipRect

This is used to clip a child by using a rectangular shape. To make the result obvious, in this example, the child is wrapped inside an Align widget with both widthFactor and heightFactor of 0.75, using top left alignment.

  child: ClipRect(
    child: Container(
      child: Align(
        alignment: Alignment.topLeft,
        widthFactor: 0.75,
        heightFactor: 0.75,
        child: Image.network(
            'https://i.ibb.co/1vXpqVs/flutter-logo.jpg'
        ),
      ),
    ),
  ),

As you can see, the child is clipped by a rectangular shape.

Flutter ClipRect

ClipRRect

It's very similar to ClipRect, but with rounded corners. You can set the border radius using borderRadious option which is of type BorderRadius.

  child: ClipRRect(
    borderRadius: BorderRadius.circular(15.0),
    child: Container(
      child: Align(
        alignment: Alignment.topLeft,
        widthFactor: 0.75,
        heightFactor: 0.75,
        child: Image.network(
            'https://i.ibb.co/1vXpqVs/flutter-logo.jpg'
        ),
      ),
    ),
  ),

Below is the result:

Flutter ClipRRect

ClipPath

It's a widget that clips its child using a path. You have to pass a custom clipper to make it useful. Otherwise, the clip will be a rectangle and it's better to use ClipRect. Clipping a path is more expensive than using built-in clippers. Therefore, only use ClipPath if you really need it.

  child: ClipPath(
    clipper: MyCustomClipper(),
    child: Image.network(
      'https://i.ibb.co/1vXpqVs/flutter-logo.jpg',
    ),
  ),

Here's the implementation of MyCustomClipper

To create the custom clipper, create a class that extends CustomClipper<Path>. There are two methods you have to override. The first one is Path getClip(Size size) in which you need to return a Path. What you need to do is defining a closed path which goes through several points.

The other method is bool shouldReclip(TriangleClipper oldClipper). It's called whenever a new instance of the custom clipper delegate class is provided to the clip object. If it returns true, getClip will be called. However, it's also possible that getClip is still called even if it returns false, for example because the box size changes.

  class MyCustomClipper extends CustomClipper<Path> {
    @override
    Path getClip(Size size) {
      final path = Path();
      path.lineTo(size.width, 0.0);
      path.lineTo(size.width * 0.75, size.height);
      path.lineTo(size.width * 0.25, size.height);
      path.close();
      return path;
    }
  
    @override
    bool shouldReclip(CustomClipper oldClipper) {
      return false;
    }
  }

Flutter - ClipPath