drawArrow method

void drawArrow(
  1. Offset arrowStart,
  2. Offset arrowEnd,
  3. {Paint painter,
  4. double width}
)

BASED OFF https://www.codeproject.com/Questions/125049/Draw-an-arrow-with-big-cap

Implementation

void drawArrow(Offset arrowStart, Offset arrowEnd,
    {Paint painter, double width}) {
  double arrowMultiplier = width ?? 3;

  //tip of the arrow
  Offset arrowPoint = arrowEnd;

  //determine arrow length
  double arrowLength = sqrt(pow(_abs(arrowStart.dx - arrowEnd.dx), 2) +
      pow(_abs(arrowStart.dy - arrowEnd.dy), 2));

  //determine arrow angle
  double arrowAngle = atan2(
      _abs(arrowStart.dy - arrowEnd.dy), _abs(arrowStart.dx - arrowEnd.dx));

  //get the x,y of the back of the point

  //to change from an arrow to a diamond, change the 3
  //in the next if/else blocks to 6

  double pointX, pointY;
  if (arrowStart.dx > arrowEnd.dx) {
    pointX = arrowStart.dx -
        (cos(arrowAngle) * (arrowLength - (3 * arrowMultiplier)));
  } else {
    pointX = cos(arrowAngle) * (arrowLength - (3 * arrowMultiplier)) +
        arrowStart.dx;
  }

  if (arrowStart.dy > arrowEnd.dy) {
    pointY = arrowStart.dy -
        (sin(arrowAngle) * (arrowLength - (3 * arrowMultiplier)));
  } else {
    pointY = (sin(arrowAngle) * (arrowLength - (3 * arrowMultiplier))) +
        arrowStart.dy;
  }

  Offset arrowPointBack = Offset(pointX, pointY);

  //get the secondary angle of the left tip
  double angleB =
      atan2((3 * arrowMultiplier), (arrowLength - (3 * arrowMultiplier)));

  double angleC =
      pi * (90 - (arrowAngle * (180 / pi)) - (angleB * (180 / pi))) / 180;

  //get the secondary length
  double secondaryLength = (3 * arrowMultiplier) / sin(angleB);

  if (arrowStart.dx > arrowEnd.dx) {
    pointX = arrowStart.dx - (sin(angleC) * secondaryLength);
  } else {
    pointX = (sin(angleC) * secondaryLength) + arrowStart.dx;
  }

  if (arrowStart.dy > arrowEnd.dy) {
    pointY = arrowStart.dy - (cos(angleC) * secondaryLength);
  } else {
    pointY = (cos(angleC) * secondaryLength) + arrowStart.dy;
  }

  //get the left point
  Offset arrowPointLeft = Offset(pointX, pointY);

  //move to the right point
  angleC = arrowAngle - angleB;

  if (arrowStart.dx > arrowEnd.dx) {
    pointX = arrowStart.dx - (cos(angleC) * secondaryLength);
  } else {
    pointX = (cos(angleC) * secondaryLength) + arrowStart.dx;
  }

  if (arrowStart.dy > arrowEnd.dy) {
    pointY = arrowStart.dy - (sin(angleC) * secondaryLength);
  } else {
    pointY = (sin(angleC) * secondaryLength) + arrowStart.dy;
  }

  Offset arrowPointRight = Offset(pointX, pointY);

  //create the point list
  List<Offset> arrowPoints = [
    arrowPoint,
    arrowPointLeft,
    arrowPointBack,
    arrowPointRight
  ];
  // todo: remove
  Path arrowPath = Path()..addPolygon(arrowPoints, true);

  //define paint
  Paint paint = painter ?? Paint();

  //draw
  this.drawPath(arrowPath, paint);
  this.drawLine(
      arrowStart, arrowPointBack, paint..strokeWidth = arrowMultiplier * 2);
}