Flutter custom design for a circular progress bar

38 views Asked by At

I'm working on a flutter project and was requested to replicate this progress bar:

requested progress

I went on to try CustomPainter and it got me to a point where it looks somewhat similar, just flatter without the shadows that makes the progress in the image look more 3 dimensional. This is my current code:

class GradientCirclePainter extends CustomPainter {
  final double progress;

  GradientCirclePainter({required this.progress});

  @override
  void paint(Canvas canvas, Size size) {

    final double innerRadius = size.width / 2 - 21;
    final double innerShadowRadius = size.width / 2 - 30;
    final double outerRadius = size.width / 2;

    final Rect rect = Rect.fromCircle(center: size.center(Offset.zero), radius: outerRadius);
    const double startAngle = -0.5 * pi;
    final double sweepAngle = 2 * pi * progress;

    final Paint trackPaint = Paint()
      ..strokeWidth = 20.0
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round
      ..color = const Color.fromARGB(255, 229, 234, 236);
      
    final Paint progressPaint = Paint()
      ..strokeWidth = 20.0
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round
      ..shader = const LinearGradient(
        colors: [Color(0xFFC2B18A), Color(0xFFA3906B)],
      ).createShader(Rect.fromCircle(center: size.center(Offset.zero), radius: size.width / 2));

    final Paint innerCirclePaint = Paint()
      ..strokeWidth = 20.0
      ..style = PaintingStyle.stroke
      ..strokeCap = StrokeCap.round
      ..color = const Color(0xFFF8F8FB);
      
    final Paint innerShadowPaint = Paint()
        ..shader = RadialGradient(
          center: Alignment.center,
          colors: [const Color(0xFFE4F3FB).withOpacity(0.2), Colors.transparent],
          stops: const [0.45, 1.0],
      ).createShader(Rect.fromCircle(center: size.center(Offset.zero), radius: outerRadius))
      ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 5.0,);

    canvas.drawCircle(size.center(Offset.zero), innerShadowRadius, innerShadowPaint);
    canvas.drawCircle(size.center(Offset.zero), outerRadius, trackPaint);
    canvas.drawCircle(size.center(Offset.zero), innerRadius, innerCirclePaint);
    canvas.drawArc(rect, startAngle, sweepAngle, false, progressPaint);
  }

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

class GradientCircle extends StatelessWidget {
  final double progress;

  const GradientCircle({super.key, required this.progress});

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: GradientCirclePainter(progress: progress),
      size: const Size(double.infinity, double.infinity), // Adjust the size as needed
    );
  }
}

Which looks like:

enter image description here

Any help or hints on how to make it look more like the requested progress look will be great. Thanks a lot!

0

There are 0 answers