createArrowPath static method

Path createArrowPath(
  1. ArrowGeometry geometry,
  2. ArrowConfig config
)

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;
}