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 { 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 oldClipper) { if (oldClipper is EqualCutCornerClipper) { return oldClipper.cutSize != cutSize || oldClipper.corner != corner; } return true; } } enum CutCorner { topLeft, topRight, bottomLeft, bottomRight }