createArrowPath static method
Implementation
static Path createArrowPath(ArrowGeometry geometry, ArrowConfig config) {
if (config.shape == ArrowShape.smallTriangle) {
final r = config.tipRoundness.clamp(0, geometry.baseEdgeA.distance - 0.1);
final Path p = Path();
p.moveTo(geometry.baseEdgeA.dx, geometry.baseEdgeA.dy);
p.lineTo(geometry.baseEdgeB.dx, geometry.baseEdgeB.dy);
if (r > 0) {
Offset shorten(Offset from, Offset to) {
final v = to - from;
final len = v.distance;
if (len <= 0.0001) return to;
final cut = math.min(r, len * 0.6);
final scale = (cut / len).toDouble();
return to - v * scale;
}
final p1 = shorten(geometry.baseEdgeB, geometry.tip);
final p2 = shorten(geometry.baseEdgeA, geometry.tip);
p.lineTo(p1.dx, p1.dy);
p.quadraticBezierTo(geometry.tip.dx, geometry.tip.dy, p2.dx, p2.dy);
p.lineTo(geometry.baseEdgeA.dx, geometry.baseEdgeA.dy);
p.close();
return p;
} else {
p.lineTo(geometry.tip.dx, geometry.tip.dy);
p.close();
return p;
}
}
final Path path = Path();
final Offset cornerStart = getCornerStartPoint(geometry, config);
final Offset cornerEnd = getCornerEndPoint(geometry, config);
path.moveTo(cornerStart.dx, cornerStart.dy);
path.arcToPoint(cornerEnd,
radius: Radius.circular(config.cornerRadius),
clockwise: isClockwiseCorner(config));
final Offset control1 = Offset.lerp(geometry.baseEdgeA, geometry.tip, 0.4)!;
final Offset control2 = Offset.lerp(geometry.baseEdgeB, geometry.tip, 0.4)!;
path.lineTo(geometry.baseEdgeA.dx, geometry.baseEdgeA.dy);
path.cubicTo(
control1.dx,
control1.dy,
geometry.tip.dx - (geometry.tip.dx - control1.dx) * 0.3,
geometry.tip.dy - (geometry.tip.dy - control1.dy) * 0.3,
geometry.tip.dx,
geometry.tip.dy,
);
path.cubicTo(
geometry.tip.dx - (geometry.tip.dx - control2.dx) * 0.3,
geometry.tip.dy - (geometry.tip.dy - control2.dy) * 0.3,
control2.dx,
control2.dy,
geometry.baseEdgeB.dx,
geometry.baseEdgeB.dy,
);
path.close();
return path;
}