From 1ec960527a37de43271573b0abe39d5377cfc354 Mon Sep 17 00:00:00 2001 From: Orion Reed Date: Fri, 20 Dec 2024 18:48:21 -0500 Subject: [PATCH] vector gizmo --- lib/folk-gizmos.ts | 40 +++++++++++++++++++ ...event-propagators-with-device-gravity.html | 34 +++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/lib/folk-gizmos.ts b/lib/folk-gizmos.ts index 25fe997..862ae31 100644 --- a/lib/folk-gizmos.ts +++ b/lib/folk-gizmos.ts @@ -19,6 +19,10 @@ interface RectOptions extends LineOptions { fill?: string; } +interface VectorOptions extends LineOptions { + size?: number; +} + /** * Visual debugging system that renders canvas overlays in DOM containers. * @@ -35,6 +39,7 @@ interface RectOptions extends LineOptions { * Gizmos.point({x, y}); * Gizmos.line(start, end, { color: 'red' }); * Gizmos.rect(domRect, { fill: 'blue' }); + * Gizmos.vector(origin, vector, { color: 'blue', width: 2, size: 10 }); * ``` */ export class Gizmos extends FolkElement { @@ -150,6 +155,41 @@ export class Gizmos extends FolkElement { ctx.stroke(); } + /** Draws a vector with an arrow head */ + static vector( + origin: Point, + vector: Point, + { color = 'blue', width = 2, size = 10, layer = Gizmos.#defaultLayer }: VectorOptions = {}, + ) { + const ctx = Gizmos.#getContext(layer); + if (!ctx) return; + + // Calculate angle and length + const angle = Math.atan2(vector.y - origin.y, vector.x - origin.x); + const arrowAngle = Math.PI / 6; // 30 degrees + + // Calculate where the line should end (where arrow head begins) + const lineEndX = vector.x - size * Math.cos(angle); + const lineEndY = vector.y - size * Math.sin(angle); + + // Draw the main line + ctx.beginPath(); + ctx.strokeStyle = color; + ctx.lineWidth = width; + ctx.moveTo(origin.x, origin.y); + ctx.lineTo(lineEndX, lineEndY); + ctx.stroke(); + + // Draw arrow head as a connected triangle + ctx.beginPath(); + ctx.moveTo(vector.x, vector.y); // Tip of the arrow + ctx.lineTo(vector.x - size * Math.cos(angle - arrowAngle), vector.y - size * Math.sin(angle - arrowAngle)); + ctx.lineTo(vector.x - size * Math.cos(angle + arrowAngle), vector.y - size * Math.sin(angle + arrowAngle)); + ctx.lineTo(vector.x, vector.y); // Back to the tip + ctx.fillStyle = color; + ctx.fill(); + } + /** Clears drawings from a specific layer or all layers if no layer specified */ static clear(layer?: string) { if (layer) { diff --git a/website/canvas/event-propagators-with-device-gravity.html b/website/canvas/event-propagators-with-device-gravity.html index ad2e5f3..df4ba0f 100644 --- a/website/canvas/event-propagators-with-device-gravity.html +++ b/website/canvas/event-propagators-with-device-gravity.html @@ -34,6 +34,11 @@ +
+ + + 3000 +

Alpha: 0

Beta: 0

Gamma: 0

@@ -58,11 +63,14 @@ rotation: from.x" > --> + +