提问人:Vito 提问时间:5/24/2023 最后编辑:Vito 更新时间:5/24/2023 访问量:67
Flutter - 自定义进度条
Flutter - custom progress bar
问:
我真的被这种弯曲的进度条困住了,带有溢出进度的自定义颜色(这些三角形)。有什么想法如何实现它吗?
这就是我目前所拥有的 - 只是一个带有价值的弯曲进度条,但我不知道如何使用这些渐变三角形前进:
class ConvexProgressPainter extends CustomPainter {
int progress;
ConvexProgressPainter({required this.progress});
@override
void paint(Canvas canvas, Size size) {
final quadraticCurve = QuadraticBezier([
vmath.Vector2(0, size.height),
vmath.Vector2(size.width / 2, 0),
vmath.Vector2(size.width, size.height),
]);
// Render main background points
final fullControlPoints = List.generate(size.width.toInt(), (index) {
final point = quadraticCurve.pointAt(index.toDouble() / size.width);
return Offset(
point.x,
point.y,
);
}).toList();
final mainSpline = CatmullRomSpline(fullControlPoints);
final mainBezierPaint = Paint()
..strokeCap = StrokeCap.round
..strokeWidth = 20
..shader = LinearGradient(colors: [
HexColor.fromHex('FFC738'),
HexColor.fromHex('FF1886'),
]).createShader(Offset(0, size.height) & size);
canvas.drawPoints(
PointMode.points,
mainSpline.generateSamples().map((e) => e.value).toList(),
mainBezierPaint,
);
// Render progress points
final progressValue = progress * (size.width / 120);
final progressControlPoints = List.generate(progressValue.toInt(), (index) {
final point = quadraticCurve.pointAt(index.toDouble() / size.width);
return Offset(
point.x,
point.y,
);
}).toList();
var progressTextAngle = 3;
final progressSpline = CatmullRomSpline(progressControlPoints);
final progressBezierPaint = Paint()
..strokeCap = StrokeCap.round
..strokeWidth = 20
..shader = LinearGradient(colors: [
HexColor.fromHex('0063FF'),
HexColor.fromHex('6000FF'),
]).createShader(Offset(0, size.height) & size);
canvas.drawPoints(
PointMode.points,
progressSpline.generateSamples().map((e) => e.value).toList(),
progressBezierPaint,
);
// rotate the canvas
canvas.save();
final radians = progressTextAngle * pi / 180;
canvas.rotate(radians);
TextSpan span = TextSpan(
style: AppTheme.caption.copyWith(color: Colors.white, fontSize: 10),
text: '$progress%');
TextPainter tp = TextPainter(text: span, textDirection: TextDirection.ltr);
tp.layout();
final x = progressControlPoints.last.dx;
final y = progressControlPoints.last.dy - tp.size.height / 2 - 2;
rotate(canvas, x, y, radians, tp);
//tp.paint(canvas, Offset(x, y));
canvas.restore();
}
void rotate(
Canvas canvas, double cx, double cy, double angle, TextPainter tp) {
// Calculate delta offset with reference to which any text should
// paint, such that the centre of the text will be
// at the given textCentrePoint
final delta = Offset(cx - tp.size.width, cy - tp.size.height);
canvas.save();
canvas.translate(cx, cy);
canvas.rotate(angle);
canvas.translate(-cx, -cy);
tp.paint(canvas, delta);
canvas.restore();
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
答:
0赞
Tim
5/24/2023
#1
我会将您的画布保留为堆栈的顶部元素,同时让红色/粉红色部分是透明的。堆栈的下层可以是略微旋转的容器,其中包含渐变。轻微的旋转是这样完成的。
new RotationTransition(
turns: new AlwaysStoppedAnimation(45 / 360),
child: Container(),
)
评论