Search code examples
flutterdartflutter-layoutflutter-custompainter

Clip Container inside CustomPainter


i made this shape using CustumPainter Class , i want the container color to fill only the shape , like a full charged battery

enter image description here

this is how i made the shape

void paint(Canvas canvas, Size size) {
    var paint = Paint();

    var path = Path();
    paint.color = Colors.black;
    paint.style = PaintingStyle.stroke;
    paint.strokeWidth = 4.0;
    var posX;
    var posY;
    
    path.lineTo(size.width*0.75, 0);


    path.lineTo(size.width*0.75, size.height*0.25);

    path.lineTo(size.width*0.75, size.height);
    path.lineTo(0, size.height);
    path.lineTo(0, 0);
    path.moveTo(size.width*0.75, size.height*0.25);
    path.lineTo(size.width*0.80, size.height*0.25);
    path.lineTo(size.width*0.80, size.height*0.75);
    path.lineTo(size.width*0.75, size.height*0.75);



    canvas.drawPath(path, paint);
  }

and this is my widget

return ClipRRect(
      child: Container(
        width: 100,
        color: Colors.red,
        height: 50,
        child: CustomPaint(
          child: Container(
          ),
          painter: BatteryPainter(),
        ),
      ),
    );

Solution

  • Create another Path/rect inside Painter to handle fill color property , Also include Paint()..strokeCap = StrokeCap.round for better look on outer side.

    , pass the value to control fill color.

    class BatteryPainter extends CustomPainter {
      final Color fillColor;
      final double value;
      BatteryPainter({
        required this.value,
        this.fillColor = Colors.red,
      });
    
      @override
      void paint(Canvas canvas, Size size) {
        var paint = Paint()..strokeCap = StrokeCap.round;
    
        var path = Path();
        paint.color = Colors.black;
        paint.style = PaintingStyle.stroke;
        paint.strokeWidth = 4.0;
    
        path.lineTo(size.width * 0.75, 0);
    
        path.lineTo(size.width * 0.75, size.height * 0.25);
    
        path.lineTo(size.width * 0.75, size.height);
        path.lineTo(0, size.height);
        path.lineTo(0, 0);
        path.moveTo(size.width * 0.75, size.height * 0.25);
        path.lineTo(size.width * 0.80, size.height * 0.25);
        path.lineTo(size.width * 0.80, size.height * 0.75);
        path.lineTo(size.width * 0.75, size.height * 0.75);
    
        Rect rect = Rect.fromLTWH(0, 0, size.width * 0.75 * value, size.height);
        canvas.drawPath(path, paint);
    
        canvas.drawRect(
            rect,
            Paint()
              ..color = fillColor
              ..style = PaintingStyle.fill);
      }
    
      @override
      bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return true;
      }
    }
    

    Use

    Container(
      width: 100,
      height: 50,
      child: CustomPaint(
        painter: BatteryPainter(value: value),
      ),
    ),
    

    enter image description here

    enter image description here