You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 18:40:37