Sunday, August 4, 2019

Flutter - Draw custom shaps with clip path.

As we know, Flutter is a Mobile UI framework by Google which allows developers to create beautiful apps for both iOS and Android with a single codebase. 

flutter clip path exampleApart from inbuilt widgets that is Flutter framework provides us, we can draw a custom shape that is called Clipping. In a Flutter application, we use clipping to create awesome looking, custom user interfaces with special effects. A widget that clips its child using a path and calling a callback on a delegate whenever the widget is to be painted. The callback returns a path and the widget prevents the child from painting outside the path.


 

In this post, we’ll talk about how to do clipping in Flutter. The ClipPath widget has clipper property which takes a CustomClipper to define how it is going to clip its path. Inside the CustomClipper there’s getClip(Size size) method where you can define how you are going to clip the child.

Creating a new Project
1.
Create a new project from File ⇒ New Flutter Project with your development IDE.

2. Let’s remove all the unwanted code from the main.dart file and start from the beginning with a bare minimum app screen that has a simple scaffold with an AppBar having the title.
  • As you can see below, first of all we have changed the app theme and disable debug banner. 
  • After that, in the build method of Stateful we have used ClipPath for draw the calculated path.

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primaryColor: const Color(0xFF02BB9F),
        primaryColorDark: const Color(0xFF167F67),
        accentColor: const Color(0xFF02BB9F),
      ),
      home: MyHomePage(title: 'Flutter Clip Path'),
    );
  }
}
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title,style: TextStyle(color:Colors.white),),
      ),
      body: Padding(
        padding: const EdgeInsets.all(30.0),
        child: ClipPath(
          child: Container(
            width: MediaQuery.of(context).size.width,
            height: 200,
            color: Colors.blue,
          ),
          clipper: CustomClipPath(),
        ),
      ),
    );
  }
}

class CustomClipPath extends CustomClipper<Path> {
  var radius=10.0;
  @override
  Path getClip(Size size) {
    Path path = Path();
    path.lineTo(0, size.height);
    path.arcToPoint(Offset(size.width, size.height),
        radius: Radius.elliptical(30, 10));
    path.lineTo(size.width, 0);
    return path;
  }
  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

  • The CustomClipper has the getClip method which you need to override and return the Path that you want to cut out. It calculates a new radius which is as close as possible to the original one.

Here, we have some variations using different path that you can use in above code base by replacing BOLD highlighted code snippet:

        

Example - 1

flutter clip path example@override
  Path getClip(Size size) {
    Path path = Path();
    path.lineTo(0, size.height - 100);
    path.quadraticBezierTo(
        size.width / 2, size.height, 
  size.width, size.height - 100);
    path.lineTo(size.width, 0);
    path.close();

    return path;
  }


Example - 2

flutter clip path example@override
  Path getClip(Size size) {
    Path path = Path();
    path.lineTo(size.width / 2, size.height);
    path.lineTo(size.width, 0.0);
    return path;
  }
  
  
  
  
  
  

Example - 3


flutter clip path example@override
  Path getClip(Size size) {
    Path path = Path();
    path.lineTo(0, size.height);
    path.quadraticBezierTo(
        size.width / 2, size.height - 100, size.width, size.height);
    path.lineTo(size.width, 0);

    return path;
  }
  
  
   


Example - 4

flutter clip path example@override
  Path getClip(Size size) {
    Path path = Path();
    path.lineTo(0, size.height);
    path.quadraticBezierTo(size.width/4, size.height
 - 40, size.width/2, size.height-20);
    path.quadraticBezierTo(3/4*size.width, size.height,
 size.width, size.height-30);
    path.lineTo(size.width, 0);

    return path;
  }
  

Example - 5
flutter clip path example@override
  Path getClip(Size size) {
    Path path = Path();
    path.lineTo(0, size.height);
    var curXPos = 0.0;
    var curYPos = size.height;
    var increment = size.width / 40;
    while (curXPos < size.width) {
      curXPos += increment;
      curYPos = curYPos == size.height ? size.height - 30 : size.height;
      path.lineTo(curXPos, curYPos);
    }
    path.lineTo(size.width, 0);

    return path;
  }

Example - 6

flutter clip path example@override
  Path getClip(Size size) {
    Path path = Path();
    path.lineTo(0, size.height);
    var curXPos = 0.0;
    var curYPos = size.height;
    var increment = size.width / 20;
    while (curXPos < size.width) {
      curXPos += increment;
      path.arcToPoint(Offset(curXPos, curYPos), radius: Radius.circular(5));
    }
    path.lineTo(size.width, 0);
    return path;
  }


Example - 7

flutter clip path example 1@override
  Path getClip(Size size) {
    Path path = Path();
    path.moveTo(radius, 0.0);
    path.arcToPoint(Offset(0.0, radius),
        clockwise: true, radius: Radius.circular(radius));
    path.lineTo(0.0, size.height - radius);
    path.arcToPoint(Offset(radius, size.height),
        clockwise: true, radius: Radius.circular(radius));
    path.lineTo(size.width - radius, size.height);
    path.arcToPoint(Offset(size.width, size.height - radius),
        clockwise: true, radius: Radius.circular(radius));
    path.lineTo(size.width, radius);
    path.arcToPoint(Offset(size.width - radius, 0.0),
        clockwise: true, radius: Radius.circular(radius));
    return path;
  }  


Here are the custom clipper clips the widget provides as it is. It’s pretty useless but you can understand how the clipping-path works.

If you have followed the article carefully, you can see the app running very smoothly as shown in the above. But if you are facing any problem or you have any quires, please feel free to ask it from the comment section.
 
Share:

Get it on Google Play

React Native - Start Development with Typescript

React Native is a popular framework for building mobile apps for both Android and iOS. It allows developers to write JavaScript code that ca...