Флаттерная краска на заказ — бритье по бокам от дуги

#flutter #canvas #custom-painter

Вопрос:

Я использую CustomPainter класс Флаттера, чтобы нарисовать фигуру, похожую на ломтики пиццы. Это несколько дуг, образующих круг. Мне нужно создать желоб между дугами.

Я попытался изменить параметры на canvas.drawArc ( startAngle и sweepAngle ), которые работают, но это не совсем то, что я хочу.

Прямо сейчас мой желоб там, но стороны дуги соприкасаются в центре, а это не тот вид, к которому я стремлюсь. То, что я хочу, — это в основном сбрить стороны нарисованной дуги, чтобы она переходила от моего существующего решения (слева) к желаемому (справа).:

введите описание изображения здесь

Я предполагаю, что мне нужно обрезать существующую форму, но я не уверен, как этого добиться.

Это пример моего CustomPainter класса:

 
class PizzaCounterShape extends CustomPainter {
  PizzaCounterShape({
    required this.count,
    required this.maxCount,
    required this.gutterWidth,
    required this.startAngle,
    required this.backgroundColor,
    required this.foregroundColor,
  }) {
    partInRadians = PizzaCounter.circleRadians / maxCount;
    sweepAngle = (pi / maxCount);
  }

  final int count;
  final int maxCount;
  final double gutterWidth;
  final double startAngle;
  final Color backgroundColor;
  final Color foregroundColor;
  late double partInRadians;
  late double sweepAngle;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height),
        Paint()..color = Colors.blue);

    final arcPaint = Paint()
      ..color = backgroundColor
      ..strokeWidth = 5
      ..strokeCap = StrokeCap.round;

    final rect = Rect.fromCenter(
      center: Offset(size.width / 2, size.height / 2),
      height: size.height,
      width: size.width,
    );

    List<int>.generate(maxCount, (i) => i).forEach((i) {
      _paintArc(
          canvas: canvas, rect: rect, paint: arcPaint, index: i);
    });
  }

  void _paintArc({
    required Canvas canvas,
    required Rect rect,
    required Paint paint,
    required int index,
  }) {
    final partStartAngle = _getStartAngle(index);
    final partSweepAngle = partInRadians - gutterWidth;
    final active = (index   1) <= count;

    paint.color = active ? foregroundColor : backgroundColor;

    canvas.drawArc(
        rect,
        partStartAngle,
        partSweepAngle,
        true,
        paint);
  }

  double _getStartAngle(int index) {
    final baseStartAngle = startAngle   (partInRadians * index);

    return baseStartAngle < PizzaCounter.circleRadians
        ? baseStartAngle
        : baseStartAngle - PizzaCounter.circleRadians;
  }


  @override
  bool shouldRepaint(PizzaCounterShape oldDelegate) {
    return 
        oldDelegate.count != count
        || oldDelegate.maxCount != maxCount
        || oldDelegate.gutterWidth != gutterWidth
        || oldDelegate.startAngle != startAngle
        || oldDelegate.foregroundColor != foregroundColor
        || oldDelegate.backgroundColor != backgroundColor;
  }
}


 

maxCount переменная указывает количество срезов, составляющих круг.