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
相关产品推荐
相关产品推荐

