How to make custom paint like eaten portion in flutter?

670 Views Asked by At

What I want to get

I want to get with custom painter something just like this. How I can draw it? For me not problem borders, gradients. I couldn't draw left part of my assets card. Please, help!

1

There are 1 best solutions below

2
On

You can use shader on Paint to have gradient effect.

Paint paint = Paint()
  ..shader = const LinearGradient(
    colors: [
      Color.fromARGB(255, 141, 23, 15),
      Colors.red,
    ],
    begin: Alignment.topCenter,
    end: Alignment.bottomCenter,
  ).createShader(
    Rect.fromLTRB(0, 0, size.width, size.height),
  )

Run on dartPad

enter image description here

The shape class

class EatenShape extends CustomPainter {
  final double gap = 4.0;

  final double radius;

  final Radius _border;

  final Color canvasColor;

  EatenShape({
    this.radius = 40,
    required this.canvasColor,
  }) : _border = Radius.circular(radius);

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..shader = const LinearGradient(
        colors: [
          Color.fromARGB(255, 141, 23, 15),
          Colors.red,
        ],
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
      ).createShader(
        Rect.fromLTRB(0, 0, size.width, size.height),
      )
      ..style = PaintingStyle.fill;

    final _rect = Rect.fromLTRB(
      0,
      gap,
      size.height - gap * 2,
      size.height - gap,
    );

    ///left Circle
    Path fullPath = Path()
      ..addOval(_rect)

      ///eaten shape
      ..addRRect(
        RRect.fromLTRBAndCorners(
          size.height * .5,
          0,
          size.width,
          size.height,
          bottomLeft: _border,
          topLeft: _border,
          bottomRight: _border,
          topRight: _border,
        ),
      );

    Path drawPath = Path()..addPath(fullPath, Offset.zero);

    canvas.drawPath(drawPath, paint);

    Paint holoPaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = gap
      ..color = canvasColor;
    canvas.drawOval(_rect, holoPaint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

I've tried with Path's fillType, not sure about the issue I've faced there. Another thing can be done just using Container with decoration without using CustomPaint.

You can use this paint as

SizedBox(
  width: 300,
  height: 70,
  child: Stack(
    children: [
      Positioned.fill(
        child: CustomPaint(
          painter: EatenShape(
            canvasColor: Theme.of(context).scaffoldBackgroundColor,
          ),
        ),
      ),
    ],
  ),
),