Flutter地图中绘制自定义重复图案折线及方向适配问题
在Flutter中实现沿折线重复的自定义图案折线(适配曲线)
核心思路
放弃直接用ImageShader整体填充路径,改为沿折线的切线方向逐段绘制图案,通过计算每段的切线角度、偏移量保证图案贴合折线走向,同时适配线宽。
具体实现步骤
拆分折线为微小线段
用PathMetrics提取路径的度量信息,将原始折线拆分成一系列短直线段,线段越短,曲线处的图案贴合度越高:final pathMetrics = path.computeMetrics(); for (final metric in pathMetrics) { const step = 5.0; // 控制分段精度,值越小曲线越平滑 for (var distance = 0.0; distance < metric.length; distance += step) { final tangent = metric.getTangentForOffset(distance)!; final position = tangent.position; final angle = tangent.angle; // 处理当前分段的图案绘制 } }逐段绘制并适配参数
针对每个分段完成以下操作:- 旋转图案:通过
canvas.save()和canvas.rotate()让图案方向与折线切线一致 - 适配线宽:将图案高度缩折线的线宽值,宽度保持自定义重复尺寸
- 对齐位置:将图案中心对齐到折线当前位置,避免偏移
示例代码片段:
final lineWidth = 10.0; // 目标折线宽度 final patternSize = Size(15.0, lineWidth); // 图案尺寸,高度匹配线宽 canvas.save(); canvas.translate(position.dx, position.dy); canvas.rotate(angle); // 替换为你的自定义图案(示例用矩形,实际可改为Image绘制) canvas.drawRect( Rect.fromCenter(center: Offset(0, 0), width: patternSize.width, height: patternSize.height), Paint()..color = Colors.blue, ); canvas.restore();- 旋转图案:通过
实现无缝重复
- 将分段的
step值设置为图案的宽度,保证相邻图案无缝拼接 - 如果用图片作为图案,提前将图片缩放到适配线宽的高度,避免绘制时重复缩放损耗性能
- 将分段的
结合flutter_map使用
在flutter_map的Polyline中自定义builder,返回包含CustomPaint的Widget:Polyline( points: yourPointsList, builder: (context, points, canvas, size) { final path = Path() ..addPolygon(points.map((p) => p.toOffset()).toList(), false); return CustomPaint(painter: PatternPolylinePainter(path, lineWidth, yourPatternImage)); }, )
关键注意事项
- 性能平衡:
step值过小会增加绘制开销,过大则曲线处图案会有棱角,可根据地图缩放级别动态调整 - 坐标转换:在flutter_map中需将地图坐标正确转换为画布坐标,确保图案绘制位置准确
内容的提问来源于stack exchange,提问作者Apri
相关产品推荐
相关产品推荐

