Flutter提供了用于处理一组特定形状的各种小部件,例如ClipRect,ClipRRect和ClipOval。但是还有ClipPath,我们可以使用它创建任何类型的形状。
在本文中,我们将重点介绍使用ClipPath和CustomClipper可以执行的操作。走!
内容:
- 剪切路径
- lineTo
- 搬去
- 二次贝塞尔曲线
- 对
- arcToPoint
- arcTo
- addRect
- addRRect
- addOval
- addPolygon
- addPath
- relativeLineTo
剪切路径
感谢ClipPath,我们可以创建非常复杂和不寻常的形状。ClipPath 的clipper属性将帮助我们实现这一目标。
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
body: Center(
child: ClipPath(
clipper: MyCustomClipper(), // <--
child: Container(
width: 200,
height: 200,
color: Colors.pink,
),
),
),
);
}
Clipper的值必须是CustomClipper<Path>
两个方法继承并重写的类的实例。
class MyCustomClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
Path path = Path();
return path;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false
}
getClip , . Size
, , hild
ClipPath
.
shouldReclip , clipper
. , true
, – false
.
CustomClipper
. , .
, (x
,y
). x
, y
– . , (0
, 0
).
. .
lineTo
.
(a), p1(0, 0)
. p2(0, h)
, – p3(w, h)
. p3
p1
, .
(b) .
@override
Path getClip(Size size) {
Path path = Path()
..lineTo(0, size.height) // p1p2
..lineTo(size.width, size.height) // p2p3
..close();
return path;
}
moveTo
.
, (0, 0)
p1(w/2, 0)
.
@override
Path getClip(Size size) {
Path path = Path() // (0, 0)
..moveTo(size.width/2, 0) // (width/2, 0)
..lineTo(0, size.width)
..lineTo(size.width, size.height)
..close();
return path;
}
quadraticBezierTo
.
, , . P0 – , P1 – , P2 – .
(), p2(0, h)
p3(w, h)
c(w/2, h/2)
.
@override
Path getClip(Size size) {
// , quadraticBezierTo
var controlPoint = Offset(size.width / 2, size.height / 2);
var endPoint = Offset(size.width, size.height);
Path path = Path()
..moveTo(size.width / 2, 0)
..lineTo(0, size.height)
..quadraticBezierTo(
controlPoint.dx, controlPoint.dy, endPoint.dx, endPoint.dy)
..close();
return path;
}
cubicTo
2 .
.
(a), p2
p3
c1
c2
.
@override
Path getClip(Size size) {
var controlPoint1 = Offset(50, size.height - 100);
var controlPoint2 = Offset(size.width - 50, size.height);
var endPoint = Offset(size.width, size.height - 50);
Path path = Path()
..moveTo(size.width / 2, 0)
..lineTo(0, size.height - 50)
..cubicTo(controlPoint1.dx, controlPoint1.dy, controlPoint2.dx,
controlPoint2.dy, endPoint.dx, endPoint.dy)
..close();
return path;
}
arcToPoint
. , , ( / ).
. , (x, y)
, – R
.
(a) , p1
. p2
p3
, , , , . p4
p5
(. – ). p6
p7
, . p8
p1
, .
@override
Path getClip(Size size) {
double radius = 20;
Path path = Path()
..moveTo(radius, 0)
..lineTo(size.width-radius, 0)
..arcToPoint(Offset(size.width, radius))
..lineTo(size.width, size.height - radius)
..arcToPoint(Offset(size.width - radius, size.height),radius: Radius.circular(radius))
..lineTo(radius, size.height)
..arcToPoint(Offset(0, size.height - radius), radius: Radius.circular(radius), clockwise: false)
..lineTo(0, radius)
..arcToPoint(Offset(radius, 0), radius: Radius.elliptical(40, 20))
..close();
return path;
}
arcTo
, , Rect, (startAngle) (sweepAngle).
. 0 PI ( PI ~3.14), – 2 PI.
Rect, , , LTRB (Left, Top, Right, Bottom) LTWH (Left, Top, Width, Height). (a) .
@override
Path getClip(Size size) {
double radius = 50;
Path path = Path()
..lineTo(size.width - radius, 0)
..arcTo(
Rect.fromPoints(
Offset(size.width - radius, 0), Offset(size.width, radius)), // Rect
1.5 * pi, //
0.5 * pi, //
true) //
..lineTo(size.width, size.height - radius)
..arcTo(Rect.fromCircle(center: Offset(size.width - radius, size.height - radius), radius: radius), 0, 0.5 * pi, false)
..lineTo(radius, size.height)
..arcTo(Rect.fromLTRB(0, size.height - radius, radius, size.height), 0.5 * pi, 0.5 * pi, false)
..lineTo(0, radius)
..arcTo(Rect.fromLTWH(0, 0, 70, 100), 1 * pi, 0.5 * pi, false)
..close();
return path;
}
addRect
. Rect
: fromPoints
, fromLTWH
, fromCircle
, fromLTRB
fromCircle
.
@override
Path getClip(Size size) {
Path path = Path()
..addRect(Rect.fromPoints(Offset(0, 0), Offset(60, 60)))
..addRect(Rect.fromLTWH(0, size.height - 50, 50, 50))
..addRect(Rect.fromCircle(center: Offset(size.width / 2, size.height / 2), radius: 20))
..close();
return path;
}
addRRect
. , , .
@override
Path getClip(Size size) {
double radius = 10;
Path path = Path()
..addRRect(RRect.fromLTRBR(0, 0, 60, 60, Radius.circular(radius)))
..addRRect(RRect.fromRectAndRadius(
Rect.fromLTWH(0, size.height - 50, 50, 50), Radius.circular(radius)))
..addRRect(RRect.fromRectAndCorners(
Rect.fromCircle(
center: Offset(size.width / 2, size.height / 2), radius: 30
),
topLeft: Radius.circular(radius)))
..close();
return path;
}
addOval
. addRect
, Rect
.
@override
Path getClip(Size size) {
Path path = Path()
..addOval(Rect.fromPoints(Offset(0, 0), Offset(60, 60)))
..addOval(Rect.fromLTWH(0, size.height - 50, 100, 50))
..addOval(Rect.fromCircle(center: Offset(size.width / 2, size.height / 2), radius: 20))
..close();
return path;
}
addPolygon
@override
Path getClip(Size size) {
var points = [
Offset(size.width / 2, 0), // p1
Offset(0, size.height / 2), // p2
Offset(size.width / 2, size.height), // p3
Offset(size.width, size.height / 2) // p4
];
Path path = Path()
..addPolygon(points, false)
..close();
return path;
}
addPath
, . .
(a), (path 1
path 2
), path 1
, path 2
path 1
. path 2
(w/2, 0)
, (0, 0)
.
@override
Path getClip(Size size) {
Path path1 = Path()
..lineTo(0, size.height)
..lineTo(size.width/2, size.height)
..lineTo(0, 0);
Path path2 = Path()
..lineTo(size.width/2, size.height)
..lineTo(size.width/2, 0)
..lineTo(0, 0);
path1.addPath(path2, Offset(size.width/2,0));
return path1;
}
relativeLineTo
lineTo
, , .
(a) p1p2
relativeLineTo
, p2
p1
. p2(x, y) = (p1.x + 50, p1.y + h)
@override
Path getClip(Size size) {
Path path = Path()
..moveTo(size.width/2, 0)
..relativeLineTo(50, size.height)
..lineTo(size.width , size.height)
..close();
return path;
}
:relativeMoveTo
,relativeQuadraticBezierTo
,relativeArcToPoint
,relativeCubicTo
quadraticBezierTo
,arcToPoint
,cubicTo
,relativeLineTo
lineTo
.
我希望这种材料对您有用,并帮助您创建新的酷造型。
- Github上的源代码
- 使用以下命令创建的Flutter_chat_bubble项目
CustomClipper