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

Flutter中如何绘制填充线条的圆形?

Flutter Canvas 绘制填充线条圆形的简便方法

不用手动计算每条线条的点位,有两种省心的实现方式:

方法一:裁剪线条区域

先绘制铺满画布的重复线条,再用圆形路径裁剪掉圆外部分,只保留圆内的线条:

class LineFilledCirclePainter extends CustomPainter {
  final double lineWidth;
  final double lineSpacing;
  final Color lineColor;
  final Color circleColor;

  LineFilledCirclePainter({
    required this.lineWidth,
    required this.lineSpacing,
    required this.lineColor,
    required this.circleColor,
  });

  @override
  void paint(Canvas canvas, Size size) {
    // 绘制圆形底色
    final circleBgPaint = Paint()..color = circleColor;
    canvas.drawCircle(Offset(size.width/2, size.height/2), size.width/2, circleBgPaint);

    // 创建圆形裁剪路径
    final clipPath = Path()
      ..addOval(Rect.fromCircle(
        center: Offset(size.width/2, size.height/2),
        radius: size.width/2,
      ));

    // 开启裁剪
    canvas.save();
    canvas.clipPath(clipPath);

    // 绘制重复水平线条(可改成垂直/斜向)
    final linePaint = Paint()
      ..color = lineColor
      ..strokeWidth = lineWidth;

    double currentY = 0;
    while (currentY <= size.height) {
      canvas.drawLine(Offset(0, currentY), Offset(size.width, currentY), linePaint);
      currentY += lineWidth + lineSpacing;
    }

    canvas.restore();
  }

  @override
  bool shouldRepaint(covariant LineFilledCirclePainter oldDelegate) {
    return oldDelegate.lineWidth != lineWidth ||
        oldDelegate.lineSpacing != lineSpacing ||
        oldDelegate.lineColor != lineColor ||
        oldDelegate.circleColor != circleColor;
  }
}

方法二:用Shader生成线条图案

通过渐变Shader生成重复的线条纹理,直接填充到圆形中,无需额外裁剪:

class ShaderLineCirclePainter extends CustomPainter {
  final double lineWidth;
  final double lineSpacing;
  final Color lineColor;
  final Color circleColor;

  ShaderLineCirclePainter({
    required this.lineWidth,
    required this.lineSpacing,
    required this.lineColor,
    required this.circleColor,
  });

  @override
  void paint(Canvas canvas, Size size) {
    // 创建重复线条的渐变Shader
    final lineShader = LinearGradient(
      colors: [lineColor, lineColor, circleColor],
      stops: [
        0,
        lineWidth / (lineWidth + lineSpacing),
        lineWidth / (lineWidth + lineSpacing)
      ],
      tileMode: TileMode.repeated,
    ).createShader(Rect.fromLTWH(0, 0, lineWidth + lineSpacing, lineWidth + lineSpacing));

    final paint = Paint()
      ..color = circleColor
      ..shader = lineShader;

    // 绘制带线条纹理的圆形
    canvas.drawCircle(Offset(size.width/2, size.height/2), size.width/2, paint);
  }

  @override
  bool shouldRepaint(covariant ShaderLineCirclePainter oldDelegate) {
    return oldDelegate.lineWidth != lineWidth ||
        oldDelegate.lineSpacing != lineSpacing ||
        oldDelegate.lineColor != lineColor ||
        oldDelegate.circleColor != circleColor;
  }
}

两种方法都不用手动计算圆内线条的起止坐标,只需调整线条宽度、间距、颜色参数就能匹配你要的效果。

内容的提问来源于stack exchange,提问作者wxkly

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:45:29