问题
How do I "cut a hole" in a shape with flutter canvas? I have this rather complex set of shapes that is made to look like a real world object. This object has a hole in it shaped like a rounded rectangle.
I would really like to subtract a RRect from a shape, but I cannot find any information on how to do this.
canvas.clipRRect(myRRect)
just removes everything that is not covered by myRRect
. I want the opposite of that. i.e. to make a myRRect
shape hole in the current canvas shape or shapes.
回答1:
You can use Path.combine along with the difference operation to create the hole.
The custom painter :
class HolePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint();
paint.color = Colors.blue;
canvas.drawPath(
Path.combine(
PathOperation.difference,
Path()..addRRect(RRect.fromLTRBR(100, 100, 300, 300, Radius.circular(10))),
Path()
..addOval(Rect.fromCircle(center: Offset(200, 200), radius: 50))
..close(),
),
paint,
);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return null;
}
}
Usage :
class EditAvatar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Hole in rounded rectangle'),
),
body: CustomPaint(
painter: HolePainter(),
child: Container(),
),
}
}
Result :
Of course if you want the hole to be a rounded rect simply substract an RRect
instead of a Circle
.
回答2:
You can try with different BlendMode in Custom Painter, Below is one of the example which you can refer:
class MyPaint extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// below one is big circle and instead of this circle you can draw your shape here.
canvas.drawCircle(Offset(200, 200), 100, Paint()
..color = Colors.orange[200]
..style = PaintingStyle.fill);
// below the circle which you want to create a cropping part.
RRect rRect = RRect.fromRectAndRadius(Rect.fromCenter(center: Offset(200, 200), width: 75, height: 75), Radius.circular(8));
canvas.drawRRect(rRect, Paint()
..color = Colors.orange[200]
..style = PaintingStyle.fill
..blendMode = BlendMode.dstOut);
canvas.save();
canvas.restore();
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
Here, I have used BlendMode.dstOut
which will be used to show the destination sources, but only where the two sources do not overlap.
来源:https://stackoverflow.com/questions/56923884/cutting-a-hole-in-a-shape-with-flutter-canvas