Search code examples
flutterdrawing

Flutter painter draw arc with indication when passing 360 degrees


I want to draw an arc, ranging from 0 degrees to 360 degrees and beyond. When passing 360 degrees, I want to indicate the user in some way, maybe with a gap, or some shadow (see attached image, especially the 360 and 450 sample). Currently, there's no indication (bottom left corner of the image).

enter image description here

Currently I'm drawing the ring like this:

// full paint
Paint full = Paint()
  ..color = fullColor
  ..strokeCap = StrokeCap.round
  ..style = PaintingStyle.stroke
  ..strokeWidth = _strokeWidth;

// full
double arcAngle = 2 * pi * (fullPercent / 100);
canvas.drawArc(Rect.fromCircle(center: center, radius: _radius), -pi / 2,
    arcAngle, false, full);

How can I achieve such ring style?

UPDATE (solved based on moneer's answer):

// empty
final Offset center = Offset(0.5 * size.width, 0.5 * size.height);
canvas.drawCircle(center, _radius, empty);

double arcAngleStart = -0.5 * pi;
double arcAngleEnd = 2 * pi * (percent % 100 / 100);
if (percent >= 100) {
  // full
  canvas.drawCircle(center, _radius, full);
  // over
  canvas.drawArc(Rect.fromCircle(center: center, radius: _radius),
      arcAngleStart, arcAngleEnd + 0.0 * pi / 180, false, over);
  // arcAngleStart & arcAngleEnd
  arcAngleStart -= 0.25 * pi;
  arcAngleEnd += 0.25 * pi;
}

// full
canvas.drawArc(Rect.fromCircle(center: center, radius: _radius),
    arcAngleStart, arcAngleEnd, false, full);

Solution

  • You can do the gap by drawing multiple layers. You will most likely need to do this anyways (in order to draw the background) unless you come up with a different approach. Here is a sample using your code. Excuse the messiness. I'm in a bit of a hurry :)

       Paint background = Paint()
      ..color = Colors.red
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10.0;
        
        Paint middle = Paint()
      ..color = Colors.white
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10.0;
        
        Paint full = Paint()
      ..color = Colors.red
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10.0;
    
        
        double arcAngle1 = 2 * pi * (100 / 100);
    canvas.drawArc(Rect.fromCircle(center: Offset(size.height + 100, size.width + 100), radius: 50), -pi / 2,
        arcAngle1, false, background);
        
            double arcAngle2 = 2 * pi * (51 / 100);
    canvas.drawArc(Rect.fromCircle(center: Offset(size.height + 100, size.width + 100), radius: 50), -pi / 2,
        arcAngle2, false, middle);
        
    double arcAngle3 = 2 * pi * (50 / 100);
    canvas.drawArc(Rect.fromCircle(center: Offset(size.height + 100, size.width + 100), radius: 50), -pi / 2,
        arcAngle3, false, full);
    

    You will need to add conditions based on parameters passed to control what is being drawn. So for example if you need no indication just draw a full circle with a single color.