Dart中如何获取自定义Path的中点?
如何获取自定义Path的中点并在路径动画中显示标记
我的路径绘制代码
class PathPainter extends CustomPainter { PathPainter({required this.progress}); final double progress; @override void paint(Canvas canvas, Size size) { var path = createPath(size); try { PathMetric pathMetric = path.computeMetrics().first; Path extractPath = pathMetric.extractPath(0.0, pathMetric.length * progress); // 绘制路径起点圆圈 canvas.drawCircle( Offset(0, size.height), 8.0, Paint()..color = Colors.green); canvas.drawPath(extractPath, myPaint); var metric = extractPath.computeMetrics().first; final offset = metric.getTangentForOffset(metric.length)!.position; print(offset); // 尝试通过静态坐标判断中点的代码(已注释) // if (offset == const Offset(30.5, 275.8)) { // print("i am matched"); // canvas.drawCircle(Offset(30.5, 275.8), 8.0, Paint()..color = Colors.green); // } canvas.drawCircle(offset, 8.0, Paint()..color = Colors.green); } catch (e) {} } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return true; } }
需求背景
我希望在路径逐步绘制的动画过程中,在路径的中点位置添加一个圆圈标记。
已尝试的方案(均未成功)
方案一:通过静态Offset判断位置
if (offset == const Offset(30.5, 275.8)) { print("i am matched"); canvas.drawCircle(Offset(30.5, 275.8), 8.0, Paint()..color = Colors.green); }
方案二:通过路径长度判断
var length = pathMetric.length / 2; if (extractPath.computeMetrics().length == length) { canvas.drawCircle(offset, 8.0, Paint()..color = Colors.green); }
解决方案
你不需要通过静态坐标或者错误的长度判断来获取中点,直接利用PathMetric就能精准获取路径中点的坐标,并且可以根据动画进度控制是否显示这个标记:
修改后的paint方法代码如下:
@override void paint(Canvas canvas, Size size) { var path = createPath(size); try { PathMetric pathMetric = path.computeMetrics().first; double totalLength = pathMetric.length; // 获取路径中点的长度位置 double midPointLength = totalLength / 2; // 获取中点的坐标 Tangent? midTangent = pathMetric.getTangentForOffset(midPointLength); Offset midPoint = midTangent?.position ?? Offset.zero; Path extractPath = pathMetric.extractPath(0.0, totalLength * progress); // 绘制起点圆圈 canvas.drawCircle(Offset(0, size.height), 8.0, Paint()..color = Colors.green); // 绘制当前进度的路径 canvas.drawPath(extractPath, myPaint); // 获取当前绘制路径的终点坐标 var metric = extractPath.computeMetrics().first; final offset = metric.getTangentForOffset(metric.length)!.position; canvas.drawCircle(offset, 8.0, Paint()..color = Colors.green); // 当动画进度达到或超过50%时,绘制中点标记 if (progress >= 0.5) { canvas.drawCircle(midPoint, 8.0, Paint()..color = Colors.red); } // 如果需要不管进度都显示中点(即使路径还没画到),可以去掉上面的if判断 // canvas.drawCircle(midPoint, 8.0, Paint()..color = Colors.red); } catch (e) { print(e); } }
关键说明
- 精准获取中点:利用
pathMetric.getTangentForOffset(totalLength / 2)直接拿到路径中点的Tangent对象,从中提取坐标,这是最可靠的方式,不需要依赖静态坐标。 - 进度控制显示:通过
progress >= 0.5判断动画是否推进到中点位置,此时再绘制中点标记,符合你“动画推进过程中添加圆圈”的需求。 - 避免错误判断:之前的方案二错误地使用了
extractPath.computeMetrics().length(这是路径度量的数量,不是路径长度),正确的做法是直接使用原路径的总长度计算中点。
内容的提问来源于stack exchange,提问作者Abd ur Rehman
相关产品推荐
相关产品推荐

