make static method

  1. @Deprecated('This is deprecated and will be removed in a future release. Use ArrowPath.addTip instead.')
Path make({
  1. required Path path,
  2. double tipLength = 15,
  3. double tipAngle = math.pi * 0.2,
  4. bool isDoubleSided = false,
  5. bool isAdjusted = true,
})

Add an arrow to the end of the last drawn curve in the given path.

The returned path is moved to the end of the curve. Always add the arrow before moving the path, not after, else the move will be lost. After adding the arrow you can move the path, draw more and apply an arrow to the new drawn part.

If isDoubleSided is true (default to false), an arrow will also be added to the beginning of the first drawn curve.

tipLength is the length (in pixels) of each of the 2 lines making the arrow.

tipAngle is the angle (in radians) between each of the 2 lines making the arrow and the curve at this point.

If isAdjusted is true (default to true), the tip of the arrow will be rotated (not following the tangent perfectly). This improves the look of the arrow when the end of the curve as a strong curvature. Can be disabled to save performance when the arrow is flat.

If the given path is not suitable to draw the arrow head (for example if the path as no length) then the path will be returned unchanged.

Implementation

@Deprecated('This is deprecated and will be removed in a future release. Use ArrowPath.addTip instead.')
static Path make({
  required Path path,
  double tipLength = 15,
  double tipAngle = math.pi * 0.2,
  bool isDoubleSided = false,
  bool isAdjusted = true,
}) {
  final List<PathMetric> pathMetrics = path.computeMetrics().toList();
  if (pathMetrics.isEmpty) {
    /// This can happen if the path as no length (trying to draw an arrow that is too small, like less than 1 pixel).
    return path;
  }

  tipAngle = math.pi - tipAngle;
  final PathMetric lastPathMetric = pathMetrics.last;
  final PathMetric firstPathMetric = pathMetrics.first;

  final Tangent? tangentLastPath = lastPathMetric.getTangentForOffset(lastPathMetric.length);

  if (tangentLastPath == null) {
    /// This should never happen.
    return path;
  }

  final Offset originalPosition = tangentLastPath.position;

  double adjustmentAngle = 0;
  if (isAdjusted && lastPathMetric.length > 10) {
    final Tangent tanBefore = lastPathMetric.getTangentForOffset(lastPathMetric.length - 5)!;
    adjustmentAngle = _getAngleBetweenVectors(tangentLastPath.vector, tanBefore.vector);
  }

  _addFullArrowTip(
    path: path,
    tangentVector: tangentLastPath.vector,
    tangentPosition: tangentLastPath.position,
    tipLength: tipLength,
    tipAngle: tipAngle,
    adjustmentAngle: adjustmentAngle,
  );

  if (isDoubleSided) {
    /// This path is double side, add the other arrow tip.
    final Tangent? tangentFirstPath = firstPathMetric.getTangentForOffset(0);
    if (tangentFirstPath != null) {
      if (isAdjusted && firstPathMetric.length > 10) {
        final Tangent tanBefore = firstPathMetric.getTangentForOffset(5)!;
        adjustmentAngle = _getAngleBetweenVectors(tangentFirstPath.vector, tanBefore.vector);
      }

      _addFullArrowTip(
        path: path,
        tangentVector: -tangentFirstPath.vector,
        tangentPosition: tangentFirstPath.position,
        tipLength: tipLength,
        tipAngle: tipAngle,
        adjustmentAngle: adjustmentAngle,
      );
    }
  }

  path.moveTo(originalPosition.dx, originalPosition.dy);

  return path;
}