Graphics arrow

Great fun.

/**
 * Draw an arrow on a Graphics Game Object.
 *
 * The arrowhead is an isosceles triangle of the given `width` and `height`.
 *
 * @param {Phaser.GameObjects.Graphics} graphics
 * @param {number} x1 - The x coordinate of the start point of the line.
 * @param {number} y1 - The y coordinate of the start point of the line.
 * @param {number} x2 - The x coordinate of the end point of the line.
 * @param {number} y2 - The y coordinate of the end point of the line.
 * @param {number} width - The width of the arrowhead, perpendicular to the line.
 * @param {number} height - The length of the arrowhead, parallel to line.
 * @param {boolean} [fill=false] - Fill the arrowhead (true) or stroke it (false).
 */
function arrow(graphics, x1, y1, x2, y2, width, height, fill = false) {
  graphics.lineBetween(x1, y1, x2, y2);

  const dx = x2 - x1;
  const dy = y2 - y1;

  const lineLength = Math.sqrt(dx * dx + dy * dy);

  // Line unit vector
  const udx = dx / lineLength;
  const udy = dy / lineLength;

  // Perpendicular unit vector
  const pdx = -udy;
  const pdy = udx;

  // Arrowhead base vertices
  const x3 = x2 - height * udx + width * pdx;
  const y3 = y2 - height * udy + width * pdy;
  const x4 = x2 - height * udx - width * pdx;
  const y4 = y2 - height * udy - width * pdy;

  if (fill) {
    graphics.fillTriangle(x2, y2, x3, y3, x4, y4);
  } else {
    graphics.beginPath().moveTo(x3, y3).lineTo(x2, y2).lineTo(x4, y4).strokePath();
  }
}
3 Likes