1

Is it possible to achieve or stack paint object over another like this. I tried many resources for custom painter but was not able to stack the text in center of the circle and applying gradient behind circle. Help appreciated.

Custom Paint Shape

Kaushik Chandru
  • 15,510
  • 2
  • 12
  • 30
Pushpendra Pal
  • 115
  • 1
  • 14

2 Answers2

1

You don't need Custom paint to achieve this. You can create the layout using stack like the following

Stack(
          children: [
            Container(
              decoration: BoxDecoration(
                  gradient: LinearGradient(
                      colors: [
                        Colors.orangeAccent.withOpacity(0.4),
                        Colors.transparent
                      ],
                      begin: Alignment.bottomCenter,
                      end: Alignment.topCenter,
                      stops: [0.4, 1])),
              width: 100,
              height: 200,
            ),
            Container(
              decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.deepPurple,
                  border: Border.all(color: Colors.white, width: 3)),
              width: 100,
              height: 100,
              child: Center(
                  child: Text(
                "80",
                style: TextStyle(
                    fontSize: 30,
                    fontWeight: FontWeight.w900,
                    color: Colors.white),
              )),
            ),
          ],
        )

preview

Kaushik Chandru
  • 15,510
  • 2
  • 12
  • 30
  • Actually it is part of a graph and for creating custom segment I needed this kind of modification but the only problem is that I was facing the alignment of text on circles – Pushpendra Pal Jul 27 '22 at 05:31
1

You can use Kaushik's answer, it's simpler and straight forward. However, if you have to use CustomPaint, here's how I would do it:

@override
void paint(Canvas canvas, Size size) {
  // top left point of shader rectangle
  var pointA = Offset(size.width * 0.2, 0);
  // define rectangle
  var rect = pointA & Size(size.width * 0.6, size.height);

  // Define a paint with shader
  final Paint shaderPaint = Paint()
    ..color = Colors.yellow
    ..style = PaintingStyle.fill
    ..strokeWidth = 1
    ..shader = const LinearGradient(
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
        colors: [
          Colors.deepPurple,
          Colors.yellow,
        ]).createShader(rect);
  // draw rectangle
  canvas.drawRect(rect, shaderPaint);

  // paint for circle
  final Paint circlePaintFill = Paint()
    ..color = Colors.deepPurple
    ..style = PaintingStyle.fill;
  final Paint circlePaintStroke = Paint()
    ..color = Colors.white
    ..style = PaintingStyle.stroke
    ..strokeWidth = 5;

  // draw circle
  canvas.drawCircle(Offset(size.width * 0.5, size.height * 0.3),
      size.width * 0.3, circlePaintFill);
  canvas.drawCircle(Offset(size.width * 0.5, size.height * 0.3),
      size.width * 0.3, circlePaintStroke);

  //draw text
  const textStyle = TextStyle(
      color: Colors.white, fontSize: 60, fontWeight: FontWeight.bold);
  const textSpan = TextSpan(
    text: '80',
    style: textStyle,
  );
  final textPainter = TextPainter(
    text: textSpan,
    textDirection: TextDirection.ltr,
  );
  textPainter.layout(
    minWidth: 0,
    maxWidth: size.width,
  );
  // position of text
  final xCenter = (size.width - textPainter.width) / 2;
  final yCenter = (size.height * 0.6 - textPainter.height) / 2;
  final offset = Offset(xCenter, yCenter);
  textPainter.paint(canvas, offset);
}

You'll have to adjust the size value inside custom painter based on the size you define outside the custom painter

Dung Ngo
  • 1,258
  • 1
  • 11
  • 24