🍭 about ClipPath
We’ve all used clipXX-related components to make rounded rectangles/circles handy, but ClipPath is the only way to implement odd-looking widgets such as pentagons/arcs.
To learn more about ClipPath, go directly to the website for the documentation, introduced as follows:
A widget that clips its child using a path.
Calls 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.
Clipping to a path is expensive.
Use path to cut the child widget.
Whenever the widget is drawn, the callback is invoked on the delegate. The callback function returns a path, and the widget prevents the Child from being drawn outside the path.
Tailoring paths is expensive.
In general, this is to cut the child widgets by path, but tailoring the path is expensive.
🦾 to see how to use
To see how this works, let’s first look at its constructor:
const ClipPath({
Key key,
this.clipper, // final CustomClipper<Path> clipper;
this.clipBehavior = Clip.antiAlias,
Widget child,
}) : assert(clipBehavior ! =null),
super(key: key, child: child);
Copy the code
First of all, you can see that there are actually two parameters needed, one is clipper, the other is child.
Child is the clipper clipper component. Write the child. The rest is the Clipper.
Take a look at clipper’s source code:
/// CustomClipper
abstract class CustomClipper<T> {
/// Creates a custom clipper.
///
/// The clipper will update its clip whenever [reclip] notifies its listeners.
const CustomClipper({ Listenable reclip }) : _reclip = reclip;
final Listenable _reclip;
// return the description of the clip -> T
T getClip(Size size);
/// Whether to re-clip
bool shouldReclip(covariant CustomClipper<T> oldClipper);
}
Copy the code
A few methods have been removed, leaving only the ones we need to rewrite, the chief of which is T getClip(Size Size).
The generic type passed in ClipPath is
/ CustomClipper
/ CustomClipper
So you just need to define your own Path to implement widgets of any shape.
😼 start implementing custom shaped widgets
Let’s implement the following shapes (original above, cropped below) :
To sum up, simply implement a CustomClipper
The code is as follows:
class MyClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
Path path = Path();
// start at 60,0
path.moveTo(60.0);
// Second order Bezier curve drawing arc
path.quadraticBezierTo(0.0.0.60);
// connect to the bottom
path.lineTo(0, size.height / 1.2);
// Third order Bezier curve drawing arc
path.cubicTo(size.width / 4, size.height, size.width / 4 * 3, size.height / 1.5, size.width, size.height / 1.2);
// connect back again
path.lineTo(size.width, 60);
// Use the second order Bezier curve to draw the arc
path.quadraticBezierTo(size.width - 60.60, size.width - 60.0);
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
Copy the code
I won’t say the logic, it’s all in the comments.
🦴 summary
Because the consumption of ClipPath is quite high, so if you just want to cut a rounded corner, or recommend to use the built-in ClipRRect, such as their performance is better (official documentation says).
ClipPath also has a static method, ClipPath. Shape ().
You can also read this article by Zhang Fengjietri – [Flutter advanced plays-shape] Path in hand, the world I have.
This article is a detailed explanation of the Path gameplay, only you can think of, without it can not do! This static method is also explained at the end.
The code has been submitted to Github – Cropping Widget Demo.
If there are defects, I hope you put forward, learn together! 🤝