draw static method

void draw({
  1. required Canvas canvas,
  2. required Offset centerPos,
  3. required double radius,
  4. required String text,
  5. required TextStyle textStyle,
  6. required TextPainter textPainter,
  7. double startAngle = 90,
  8. double endAngle = 90,
  9. ArcTextDirection textArcDirection = ArcTextDirection.Clockwise,
  10. ArcTextBaseline baseline = ArcTextBaseline.Outer,
  11. Watcher? watcher,
  12. int letterSpacing = 0,
})

Draw arc text

Parameters:

  • canvas Canvas - the canvas
  • centerPos Offset - the center position of the arc
  • radius double - the radius of the arc
  • startAngle double - the start text angle in degree format (360)
  • endAngle double - the end text angle in degree format (360)
  • textArcDirectionArcTextDirection - the direction of the text clockwise or anti-clockwise
  • text String - the display text
  • textStyle TextStyle
  • baseline ArcTextBaseline - TextArcBaseline.Inner, TextArcBaseline.Outer, TextArcBaseline.Center - how text display relative to the arc
  • textPainter TextPainter - the text painter
  • watcher Watcher - the canvas watcher
  • letterSpacing - the spacing between letters

Implementation

static void draw(
    {required Canvas canvas,
    required Offset centerPos,
    required double radius,
    required String text,
    required TextStyle textStyle,
    required TextPainter textPainter,
    double startAngle = 90,
    double endAngle = 90,
    ArcTextDirection textArcDirection = ArcTextDirection.Clockwise,
    ArcTextBaseline baseline = ArcTextBaseline.Outer,
    Watcher? watcher,
    int letterSpacing = 0}) {
  watcher ??= _DefaultWatcher();

  canvas.save();
  watcher.save();

  canvas.translate(centerPos.dx, centerPos.dy);
  watcher.translate(centerPos.dx, centerPos.dy);

  int multiplyDirection =
      textArcDirection == ArcTextDirection.Clockwise ? 1 : -1;

  double deltaAngle = _calcDeltaAngle(startAngle, endAngle, textArcDirection);
  double halfAngle = deltaAngle / 2;

  textPainter.text = TextSpan(text: text, style: textStyle);
  textPainter.layout();
  double textWidth = textPainter.size.width + (letterSpacing * text.length);
  double textHeight = textPainter.size.height;

  double arcAngleByText = v_math.degrees(textWidth / radius);
  double actualStartAngle;
  double maxAngle = deltaAngle;
  if (deltaAngle > arcAngleByText) {
    actualStartAngle = startAngle +
        multiplyDirection * halfAngle -
        multiplyDirection * arcAngleByText / 2;
  } else {
    actualStartAngle = startAngle;
  }

  if (baseline == ArcTextBaseline.Outer) {
    radius += textHeight / 2;
  } else if (baseline == ArcTextBaseline.Inner) {
    radius -= textHeight / 2;
  }

  Offset characterOffset =
      Offset(0, -radius * multiplyDirection - textHeight / 2);
  final rotationInRadian =
      v_math.radians(actualStartAngle + multiplyDirection * 90);
  canvas.rotate(rotationInRadian);
  watcher.rotate(rotationInRadian);

  double angle = 0;
  double prevIncreaseAngle = 0;

  for (String character in text.characters) {
    textPainter.text = TextSpan(text: character, style: textStyle);
    textPainter.layout();
    final characterWidth = textPainter.size.width + letterSpacing;
    final characterAngle = characterWidth / radius;

    angle += v_math.degrees(characterAngle);
    if (angle > maxAngle) {
      break;
    }
    canvas.rotate(prevIncreaseAngle);
    watcher.rotate(prevIncreaseAngle);

    prevIncreaseAngle = multiplyDirection * characterAngle;
    textPainter.paint(canvas, characterOffset);

    watcher.drawText(character, textStyle, characterOffset);
  }
  canvas.restore();
  watcher.restore();
}