Home > Enterprise >  Transparent Container Inside Opaque Parent
Transparent Container Inside Opaque Parent

Time:12-21

I'd like to create a transparent mask on top of a live camera feed that looks like this:

Desired output

The idea I had is to stack a Container on top of the CameraPreview like so:

Stack(
  alignment: Alignment.center,
  children: [
    // Camera feed first
    CameraPreview(controller!),

    // With a shaded container on top
    Container(
      color: Colors.black.withOpacity(.7),
      child: Center(

        // And a hole in the center for the transparent frame
        child: Container(
          width: 200,
          height: 100,
          color: Colors.transparent,
        ),
      ),
    ),
  ],
)

Instead of getting the desired output above, I get this:

Actual output

I mean, I can see what Flutter's thinking here -- transparent means it'll show the Container background underneath, not cut a hole in the container.

But how do I get the output I desire?

CodePudding user response:

Your Approach is correct of using layers, But our main focus is to clip out the needed section and keep the other overlay as it is. So

Layer Implementation would be like this:

Stack(
  alignment: Alignment.center,
  children: [
    // Camera feed first
    CameraPreview(controller!),

   //would be the Overlay Widget
    OverlayWithRectangleClipping()
    
  ],
)

A Separate widget is used or I can say a screen for some additional options you can just use the widget as well. The job has been carried out using Custom Painter. Later OverlayWithRectangleClipping would look like this:

class OverlayWithRectangleClipping extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.transparent,
        body: _getCustomPaintOverlay(context));
  }

  //CustomPainter that helps us in doing this
  CustomPaint _getCustomPaintOverlay(BuildContext context) {
    return CustomPaint(
        size: MediaQuery.of(context).size, painter: RectanglePainter());
  }
}


class RectanglePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = Colors.black54;

    canvas.drawPath(
        Path.combine(
          PathOperation.difference, //simple difference of following operations
          //bellow draws a rectangle of full screen (parent) size
          Path()..addRect(Rect.fromLTWH(0, 0, size.width, size.height)),
           //bellow clips out the circular rectangle with center as offset and dimensions you need to set
          Path()
            ..addRRect(RRect.fromRectAndRadius(
                Rect.fromCenter(
                    center: Offset(size.width * 0.5, size.height * 0.5),
                    width: size.width * 0.85,
                    height: size.height * 0.3),
                Radius.circular(15)))
            ..close(),
        ),
        paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

Note: Above can be implemented in many ways like the one mentioned in the comments and optimizations can be done above will get you your desired result.

CodePudding user response:

you can use "CustomPaint" in the flutter. some inspiration from image_crop

check the code

  • Related