Flutter自定义弧形进度条:渐变溢出三角形实现求助
实现弧形进度条末尾的渐变溢出三角形思路
核心思路
要实现进度条末端的渐变三角形,关键是匹配进度条曲线的切线方向绘制三角形,同时复用进度条的渐变效果保证视觉统一,具体分三步落地:
步骤1:精准获取进度终点及切线方向
现有代码通过progressControlPoints.last获取终点精度不足,建议直接从二次贝塞尔曲线计算,同时推导曲线切线方向(决定三角形朝向):
// 替换原终点获取逻辑,精准计算进度终点 final progressRatio = progressValue / size.width; final endPoint = quadraticCurve.pointAt(progressRatio); final endOffset = Offset(endPoint.x, endPoint.y); // 计算终点切线方向(用极近相邻点的斜率近似) final nextRatio = (progressRatio + 0.001).clamp(0.0, 1.0); final nextPoint = quadraticCurve.pointAt(nextRatio); final tangent = Offset(nextPoint.x - endPoint.x, nextPoint.y - endPoint.y).normalize();
步骤2:构建适配进度条的三角形路径
根据进度条的strokeWidth确定三角形大小,以终点为顶点,向切线垂直方向扩展形成三角形:
final triangleSize = progressBezierPaint.strokeWidth * 0.8; // 大小适配线条粗细 // 切线的左右垂直方向向量 final perpendicularLeft = Offset(-tangent.dy, tangent.dx) * triangleSize; final perpendicularRight = Offset(tangent.dy, -tangent.dx) * triangleSize; // 定义三角形三个顶点 final vertex1 = endOffset; final vertex2 = endOffset + perpendicularLeft + tangent * triangleSize; final vertex3 = endOffset + perpendicularRight + tangent * triangleSize; // 创建闭合三角形路径 final trianglePath = Path() ..moveTo(vertex1.dx, vertex1.dy) ..lineTo(vertex2.dx, vertex2.dy) ..lineTo(vertex3.dx, vertex3.dy) ..close();
步骤3:添加渐变并绘制三角形
复用进度条的渐变Shader,保证视觉风格统一,然后绘制填充路径:
// 复用进度条渐变,也可自定义三角形专属渐变 final trianglePaint = Paint() ..shader = LinearGradient( colors: [HexColor.fromHex('0063FF'), HexColor.fromHex('6000FF')], begin: Alignment.centerLeft, end: Alignment.centerRight, ).createShader(Rect.fromPoints(vertex2, vertex3)); canvas.drawPath(trianglePath, trianglePaint);
代码整合提示
将上述代码块添加到paint方法末尾(绘制文本之后、canvas.restore()之前),同时注意边界处理:比如进度为0时不绘制三角形,进度为100%时调整三角形朝向适配曲线末端。
内容的提问来源于stack exchange,提问作者Vito
相关产品推荐
相关产品推荐

