101 lines
2.3 KiB
Dart
101 lines
2.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
class CutCornerClipper extends StatelessWidget {
|
|
|
|
const CutCornerClipper({super.key,
|
|
this.width,
|
|
this.height,
|
|
this.cutCorner = CutCorner.topRight,
|
|
this.cutSize,
|
|
this.child,
|
|
});
|
|
|
|
final double? width;
|
|
final double? height;
|
|
final CutCorner cutCorner;
|
|
final double? cutSize;
|
|
final Widget? child;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ClipPath(
|
|
clipper: EqualCutCornerClipper(
|
|
cutSize: cutSize ?? 35,
|
|
corner: cutCorner,
|
|
),
|
|
child: Container(
|
|
width: width,
|
|
height: height,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
),
|
|
child: child,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 长方形缺一个角(等边缺角)
|
|
class EqualCutCornerClipper extends CustomClipper<Path> {
|
|
final double cutSize; // 缺角两条直角边的长度(相等)
|
|
final CutCorner corner;
|
|
|
|
const EqualCutCornerClipper({
|
|
this.cutSize = 20,
|
|
this.corner = CutCorner.topRight,
|
|
});
|
|
|
|
@override
|
|
Path getClip(Size size) {
|
|
final path = Path();
|
|
final w = size.width;
|
|
final h = size.height;
|
|
final c = cutSize;
|
|
|
|
switch (corner) {
|
|
case CutCorner.topRight:
|
|
path.moveTo(0, 0);
|
|
path.lineTo(w - c, 0); // 上边到缺角起点
|
|
path.lineTo(w, c); // 🔥 45° 斜线(两条边相等)
|
|
path.lineTo(w, h);
|
|
path.lineTo(0, h);
|
|
break;
|
|
|
|
case CutCorner.topLeft:
|
|
path.moveTo(c, 0);
|
|
path.lineTo(w, 0);
|
|
path.lineTo(w, h);
|
|
path.lineTo(0, h);
|
|
path.lineTo(0, c);
|
|
break;
|
|
|
|
case CutCorner.bottomRight:
|
|
path.moveTo(0, 0);
|
|
path.lineTo(w, 0);
|
|
path.lineTo(w, h - c);
|
|
path.lineTo(w - c, h);
|
|
path.lineTo(0, h);
|
|
break;
|
|
|
|
case CutCorner.bottomLeft:
|
|
path.moveTo(0, 0);
|
|
path.lineTo(w, 0);
|
|
path.lineTo(w, h);
|
|
path.lineTo(c, h);
|
|
path.lineTo(0, h - c);
|
|
break;
|
|
}
|
|
path.close();
|
|
return path;
|
|
}
|
|
|
|
@override
|
|
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
|
|
if (oldClipper is EqualCutCornerClipper) {
|
|
return oldClipper.cutSize != cutSize || oldClipper.corner != corner;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
enum CutCorner { topLeft, topRight, bottomLeft, bottomRight } |