Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save EsinShadrach/1366d30454e27690e39ef0543b20968c to your computer and use it in GitHub Desktop.

Select an option

Save EsinShadrach/1366d30454e27690e39ef0543b20968c to your computer and use it in GitHub Desktop.
class _RiskIndicatorPainter extends CustomPainter {
final double risk;
final Color color;
const _RiskIndicatorPainter({required this.risk, required this.color});
@override
void paint(Canvas canvas, Size size) {
const strokeWidth = 8.0;
final radius = (size.shortestSide - strokeWidth) / 2;
final center = Offset(size.width / 2, size.height / 2);
final rect = Rect.fromCircle(center: center, radius: radius);
final backgroundPaint =
Paint()
..color = color.withValues(alpha: 0.20)
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round;
final progressPaint =
Paint()
..color = color
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth
..strokeCap = StrokeCap.round;
const gapDeg = 10.0;
final capDeg = (strokeWidth / 2) / radius * 180 / math.pi;
final halfGap = (gapDeg / 2) + capDeg;
void drawSegment(double startDeg, double endDeg) {
double sweep = endDeg - startDeg;
if (sweep < 0) sweep += 360;
canvas.drawArc(
rect,
_deg2rad(startDeg),
_deg2rad(sweep),
false,
backgroundPaint,
);
}
drawSegment(-90 + halfGap, 30 - halfGap);
drawSegment(30 + halfGap, 150 - halfGap);
drawSegment(150 + halfGap, 270 - halfGap);
final segments = <List<double>>[
[-90 + halfGap, 30 - halfGap],
[30 + halfGap, 150 - halfGap],
[150 + halfGap, 270 - halfGap],
];
final totalStartDeg = -90.0;
final totalEndDeg = 270.0;
final clamped = risk.clamp(0.0, 1.0);
final progressEndDeg =
totalStartDeg + (totalEndDeg - totalStartDeg) * clamped;
for (final seg in segments) {
final segStart = seg[0];
final segEnd = seg[1];
final start = math.max(segStart, totalStartDeg);
final end = math.min(segEnd, progressEndDeg);
if (end > start) {
canvas.drawArc(
rect,
_deg2rad(start),
_deg2rad(end - start),
false,
progressPaint,
);
}
}
final fillPaint =
Paint()
..color = color.withValues(alpha: 0.10)
..style = PaintingStyle.fill;
canvas.drawCircle(center, radius - strokeWidth * 1.2, fillPaint);
}
double _deg2rad(double d) => d * math.pi / 180.0;
@override
bool shouldRepaint(covariant _RiskIndicatorPainter old) => old.risk != risk;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment