#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
переменная указывает количество срезов, составляющих круг.