Add an arrow to the Shape tool (#3343)

* add arrow shape feature in editor

Signed-off-by: krVatsal <kumarvatsal34@gmail.com>

* fix the arrow tool to show arrow in viewport space

Signed-off-by: krVatsal <kumarvatsal34@gmail.com>

* fix the direction of arrow and make the new arrow node

Signed-off-by: krVatsal <kumarvatsal34@gmail.com>

* updated arrow tool to hae start and end points

Signed-off-by: krVatsal <kumarvatsal34@gmail.com>

* fixed calculate point bug

Signed-off-by: krVatsal <kumarvatsal34@gmail.com>

* fixed some bugs of arrow positioning

Signed-off-by: krVatsal <kumarvatsal34@gmail.com>

* fixed formatting in whole codebase and added fill to arrow

Signed-off-by: krVatsal <kumarvatsal34@gmail.com>

* fix

---------

Signed-off-by: krVatsal <kumarvatsal34@gmail.com>
Co-authored-by: Timon <me@timon.zip>
This commit is contained in:
Vatsal Kumar
2026-01-12 06:28:28 +05:30
committed by GitHub
parent 479688d86b
commit 4fea2b0fe7
7 changed files with 186 additions and 8 deletions

View File

@@ -312,6 +312,37 @@ impl<PointId: Identifier> Subpath<PointId> {
Self::from_anchors([p1, p2], false)
}
/// Constructs an arrow shape from start and end points with parametric control over dimensions
pub fn new_arrow(start: DVec2, end: DVec2, shaft_width: f64, head_width: f64, head_length: f64) -> Self {
let delta = end - start;
let length = delta.length();
if length < 1e-10 {
// Degenerate case: return a point
return Self::from_anchors([start], true);
}
let direction = delta / length;
let perpendicular = DVec2::new(-direction.y, direction.x);
let half_shaft = shaft_width * 0.5;
let half_head = head_width * 0.5;
let head_base_distance = (length - head_length).max(0.);
let head_base = start + direction * head_base_distance;
let anchors = [
start - perpendicular * half_shaft, // Tail bottom
head_base - perpendicular * half_shaft, // Head base bottom (shaft)
head_base - perpendicular * half_head, // Head base bottom (wide)
end, // Tip
head_base + perpendicular * half_head, // Head base top (wide)
head_base + perpendicular * half_shaft, // Head base top (shaft)
start + perpendicular * half_shaft, // Tail top
];
Self::from_anchors(anchors, true)
}
pub fn new_spiral(a: f64, outer_radius: f64, turns: f64, start_angle: f64, delta_theta: f64, spiral_type: SpiralType) -> Self {
let mut manipulator_groups = Vec::new();
let mut prev_in_handle = None;

View File

@@ -188,16 +188,26 @@ fn star<T: AsU64>(
/// Generates a line with endpoints at the two chosen coordinates.
#[node_macro::node(category("Vector: Shape"))]
fn line(
fn arrow(
_: impl Ctx,
_primary: (),
/// Coordinate of the line's initial endpoint.
#[default(0., 0.)]
start: PixelSize,
/// Coordinate of the line's terminal endpoint.
#[default(100., 100.)]
end: PixelSize,
#[default(0., 0.)] start: PixelSize,
#[default(100., 0.)] end: PixelSize,
#[unit(" px")]
#[default(10)]
shaft_width: f64,
#[unit(" px")]
#[default(30)]
head_width: f64,
#[unit(" px")]
#[default(20)]
head_length: f64,
) -> Table<Vector> {
Table::new_from_element(Vector::from_subpath(subpath::Subpath::new_arrow(start, end, shaft_width, head_width, head_length)))
}
#[node_macro::node(category("Vector: Shape"))]
fn line(_: impl Ctx, _primary: (), #[default(0., 0.)] start: PixelSize, #[default(100., 100.)] end: PixelSize) -> Table<Vector> {
Table::new_from_element(Vector::from_subpath(subpath::Subpath::new_line(start, end)))
}