Cutting a hole in a shape with flutter canvas

情到浓时终转凉″ 提交于 2020-07-18 12:49:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!