我真的被这样的曲线进度条卡住了,它有溢出进度的自定义颜色(这些三角形)。有什么想法如何实现它?
这就是我目前所拥有的-只是一个有价值的弯曲进度条,但我不知道如何使用这些渐变三角形:
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;
}
现在看起来是这样的
1条答案
按热度按时间idfiyjo81#
我会让你的画布作为堆栈的顶部元素,同时让红色/粉色部分透明。堆叠的下层可以是稍微旋转的容器,其包含梯度。轻微的旋转是这样做的。