|
|
|
import 'dart:math' show cos, min, pi, sin;
|
|
|
|
import 'dart:math' show min, pi, asin;
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
...
|
...
|
@@ -48,7 +48,6 @@ class ProgressPainter extends CustomPainter { |
|
|
|
var centerY = wh / 2;
|
|
|
|
var radius = wh / 2 - strokeWidth / 2;
|
|
|
|
|
|
|
|
double startAngle = 0;
|
|
|
|
var rect = Rect.fromCenter(
|
|
|
|
center: Offset(centerX, centerY),
|
|
|
|
width: wh - strokeWidth,
|
|
...
|
...
|
@@ -63,7 +62,7 @@ class ProgressPainter extends CustomPainter { |
|
|
|
}
|
|
|
|
|
|
|
|
var shader = SweepGradient(
|
|
|
|
startAngle: startAngle.toRadians(),
|
|
|
|
startAngle: 0.toRadians(),
|
|
|
|
endAngle: 360.toRadians(),
|
|
|
|
colors: reverse
|
|
|
|
? progressColor[colorRangeIndex].reversed.toList()
|
|
...
|
...
|
@@ -82,11 +81,6 @@ class ProgressPainter extends CustomPainter { |
|
|
|
..strokeCap = StrokeCap.butt
|
|
|
|
..style = PaintingStyle.stroke;
|
|
|
|
|
|
|
|
var startCapPosition = Offset(
|
|
|
|
centerX + radius * cos(startAngle.toRadians()),
|
|
|
|
centerY + radius * sin(startAngle.toRadians()),
|
|
|
|
);
|
|
|
|
|
|
|
|
canvas.drawArc(
|
|
|
|
rect,
|
|
|
|
0.toRadians(),
|
|
...
|
...
|
@@ -94,7 +88,31 @@ class ProgressPainter extends CustomPainter { |
|
|
|
false,
|
|
|
|
backgroundPaint,
|
|
|
|
);
|
|
|
|
|
|
|
|
if (sweepAngle >= 0) {
|
|
|
|
double capAngle = 0;
|
|
|
|
if (radius > 0) {
|
|
|
|
capAngle = asin((strokeWidth / 2) / radius) * 180 / pi;
|
|
|
|
}
|
|
|
|
|
|
|
|
double actualCapAngle = capAngle;
|
|
|
|
if (sweepAngle < 360) {
|
|
|
|
if (sweepAngle < 2 * capAngle) {
|
|
|
|
actualCapAngle = sweepAngle / 2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
actualCapAngle = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
double startAngle = actualCapAngle;
|
|
|
|
double drawnSweepAngle = sweepAngle;
|
|
|
|
if (sweepAngle < 360) {
|
|
|
|
drawnSweepAngle = sweepAngle - 2 * actualCapAngle;
|
|
|
|
if (drawnSweepAngle < 0) {
|
|
|
|
drawnSweepAngle = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
canvas.save();
|
|
|
|
// Move the canvas origin to the center
|
|
|
|
canvas.translate(centerX, centerY);
|
|
...
|
...
|
@@ -111,9 +129,12 @@ class ProgressPainter extends CustomPainter { |
|
|
|
canvas.translate(-centerX, -centerY);
|
|
|
|
|
|
|
|
if (sweepAngle < 360) {
|
|
|
|
canvas.save();
|
|
|
|
canvas.translate(centerX, centerY);
|
|
|
|
canvas.rotate(reverse ? -startAngle.toRadians() : startAngle.toRadians());
|
|
|
|
canvas.drawArc(
|
|
|
|
Rect.fromCenter(
|
|
|
|
center: startCapPosition,
|
|
|
|
center: Offset(radius, 0),
|
|
|
|
width: strokeWidth,
|
|
|
|
height: strokeWidth,
|
|
|
|
),
|
|
...
|
...
|
@@ -122,76 +143,73 @@ class ProgressPainter extends CustomPainter { |
|
|
|
true,
|
|
|
|
Paint()..color = progressColor[0].first,
|
|
|
|
);
|
|
|
|
canvas.drawRect(
|
|
|
|
Rect.fromCenter(
|
|
|
|
center: Offset(radius, 0),
|
|
|
|
width: strokeWidth,
|
|
|
|
height: 1,
|
|
|
|
),
|
|
|
|
Paint()..color = progressColor[0].first,
|
|
|
|
);
|
|
|
|
canvas.restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
canvas.drawArc(
|
|
|
|
rect,
|
|
|
|
0.toRadians(),
|
|
|
|
reverse ? -startAngle.toRadians() : startAngle.toRadians(),
|
|
|
|
reverse
|
|
|
|
? -(startAngle + sweepAngle).toRadians()
|
|
|
|
: (startAngle + sweepAngle).toRadians(),
|
|
|
|
? -drawnSweepAngle.toRadians()
|
|
|
|
: drawnSweepAngle.toRadians(),
|
|
|
|
false,
|
|
|
|
paint,
|
|
|
|
);
|
|
|
|
if (sweepAngle < 360) {
|
|
|
|
|
|
|
|
if (sweepAngle != 360) {
|
|
|
|
final endAngle = startAngle + drawnSweepAngle;
|
|
|
|
canvas.save();
|
|
|
|
canvas.translate(centerX, centerY);
|
|
|
|
canvas.rotate(reverse ? -endAngle.toRadians() : endAngle.toRadians());
|
|
|
|
|
|
|
|
final endColor =
|
|
|
|
getColorAtAngle(sweepAngle, progressColor[colorRangeIndex]);
|
|
|
|
|
|
|
|
final bool shouldDrawShadow = sweepAngle > 360 || (sweepAngle > 355 && sweepAngle < 360);
|
|
|
|
if (shouldDrawShadow) {
|
|
|
|
//Draw arc shadow
|
|
|
|
var shadowPosition = Offset(
|
|
|
|
radius,
|
|
|
|
reverse ? -4 : 4,
|
|
|
|
);
|
|
|
|
final Paint shadowPaint = Paint()
|
|
|
|
..color = Colors.black.withOpacity(0.35)
|
|
|
|
..style = PaintingStyle.fill
|
|
|
|
..maskFilter = const MaskFilter.blur(BlurStyle.normal, 3);
|
|
|
|
canvas.drawCircle(shadowPosition, strokeWidth / 2, shadowPaint);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Draw the ending arc
|
|
|
|
canvas.drawArc(
|
|
|
|
Rect.fromCenter(
|
|
|
|
center: Offset(radius, 0),
|
|
|
|
width: strokeWidth,
|
|
|
|
height: strokeWidth,
|
|
|
|
),
|
|
|
|
0,
|
|
|
|
reverse ? -180.toRadians() : 180.toRadians(),
|
|
|
|
true,
|
|
|
|
Paint()..color = endColor,
|
|
|
|
);
|
|
|
|
canvas.drawRect(
|
|
|
|
Rect.fromCenter(
|
|
|
|
center: startCapPosition,
|
|
|
|
center: Offset(radius, 0),
|
|
|
|
width: strokeWidth,
|
|
|
|
height: 1,
|
|
|
|
),
|
|
|
|
Paint()..color = progressColor[0].first,
|
|
|
|
Paint()..color = endColor,
|
|
|
|
);
|
|
|
|
canvas.restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
canvas.translate(centerX, centerY);
|
|
|
|
if (sweepAngle < 360) {
|
|
|
|
final endCapRotate = 360 - sweepAngle;
|
|
|
|
canvas.rotate(
|
|
|
|
reverse ? endCapRotate.toRadians() : -endCapRotate.toRadians());
|
|
|
|
}
|
|
|
|
//0.1 is because the angle calculation is not accurate enough, so we need to go back a little bit.
|
|
|
|
var endCapPosition = Offset(
|
|
|
|
centerX + radius * cos((startAngle).toRadians()),
|
|
|
|
centerY + radius * sin((startAngle).toRadians()),
|
|
|
|
);
|
|
|
|
|
|
|
|
canvas.translate(-centerX, -centerY);
|
|
|
|
final endColor =
|
|
|
|
getColorAtAngle(sweepAngle, progressColor[colorRangeIndex]);
|
|
|
|
if (sweepAngle > 355) {
|
|
|
|
//Draw arc shadow
|
|
|
|
var shadowPosition = Offset(
|
|
|
|
centerX + radius * cos((startAngle).toRadians()),
|
|
|
|
centerY + (reverse ? -4 : 4) + radius * sin((startAngle).toRadians()),
|
|
|
|
);
|
|
|
|
final Paint shadowPaint = Paint()
|
|
|
|
..color = Colors.black.withOpacity(0.35)
|
|
|
|
..style = PaintingStyle.fill
|
|
|
|
..maskFilter = const MaskFilter.blur(BlurStyle.normal, 3);
|
|
|
|
canvas.drawCircle(shadowPosition, strokeWidth / 2, shadowPaint);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Draw the ending arc
|
|
|
|
canvas.drawArc(
|
|
|
|
Rect.fromCenter(
|
|
|
|
center: endCapPosition,
|
|
|
|
width: strokeWidth,
|
|
|
|
height: strokeWidth,
|
|
|
|
),
|
|
|
|
0,
|
|
|
|
reverse ? -180.toRadians() : 180.toRadians(),
|
|
|
|
true,
|
|
|
|
Paint()..color = endColor,
|
|
|
|
);
|
|
|
|
canvas.drawRect(
|
|
|
|
Rect.fromCenter(
|
|
|
|
center: endCapPosition,
|
|
|
|
width: strokeWidth,
|
|
|
|
height: 1,
|
|
|
|
),
|
|
|
|
Paint()..color = endColor,
|
|
|
|
);
|
|
|
|
|
|
|
|
// // Restore the canvas to the saved state
|
|
|
|
canvas.restore();
|
|
|
|
}
|
...
|
...
|
|