mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-28 12:26:52 -06:00
This commit is contained in:
@@ -63,3 +63,24 @@ fn finishing_the_path_clears_its_handles_and_band() {
|
||||
let ov = &s.tool.overlay;
|
||||
assert!(ov.pen.is_empty() && ov.pen_handles.is_empty() && ov.rubber.is_none() && ov.rubber_handle.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shift_keeps_the_band_and_the_next_point_at_45_degree_steps() {
|
||||
// #970: with Shift the band shows where the point will land, at a 45° step from the last
|
||||
// anchor (the same length as the pointer is away), not under the pointer.
|
||||
let mut s = Session::new();
|
||||
s.set_tool(ToolId::Pen);
|
||||
at(&mut s, PointerKind::Down, 100.0, 100.0);
|
||||
at(&mut s, PointerKind::Up, 100.0, 100.0);
|
||||
let shifted = |kind, x, y| PointerEvent { shift: true, ..PointerEvent::at(kind, x, y, 1.0) };
|
||||
s.pointer(&shifted(PointerKind::Hover, 300.0, 120.0)).unwrap();
|
||||
let [x0, y0, x1, y1] = s.tool.overlay.rubber.unwrap();
|
||||
assert_eq!([x0, y0, y1], [100.0, 100.0, 100.0], "level with the last anchor");
|
||||
assert!((x1 - (100.0 + 200f64.hypot(20.0))).abs() < 1e-9, "{x1}");
|
||||
s.pointer(&shifted(PointerKind::Down, 300.0, 120.0)).unwrap();
|
||||
s.pointer(&shifted(PointerKind::Up, 300.0, 120.0)).unwrap();
|
||||
s.pointer(&shifted(PointerKind::Hover, 400.0, 230.0)).unwrap();
|
||||
let [x0, y0, x1, y1] = s.tool.overlay.rubber.unwrap();
|
||||
assert_eq!(y0, 100.0, "the point landed on the band");
|
||||
assert!((x1 - x0 - (y1 - y0)).abs() < 1e-9, "45° down to the right: {:?}", [x0, y0, x1, y1]);
|
||||
}
|
||||
|
||||
@@ -459,6 +459,13 @@ pub(crate) enum Gesture {
|
||||
},
|
||||
}
|
||||
|
||||
/// Where Shift puts the Pen's next point: as far from `last` as `p` is, at the nearest 45° step.
|
||||
fn at_45_degrees(last: Point, p: Point) -> Point {
|
||||
let v = p - last;
|
||||
let ang = (v.atan2() / (std::f64::consts::PI / 4.0)).round() * std::f64::consts::PI / 4.0;
|
||||
last + Vec2::from_angle(ang) * v.hypot()
|
||||
}
|
||||
|
||||
/// The handles a pen path shows while it is drawn ([`Overlay::pen_handles`]): the last anchor's in
|
||||
/// and out handles and the one before's out handle, those that aren't zero.
|
||||
fn pen_handles(points: &[(Point, Vec2, Vec2)]) -> Vec<[f64; 4]> {
|
||||
@@ -1158,6 +1165,8 @@ impl Session {
|
||||
guides = g;
|
||||
self.tool.overlay.cursor = Cursor::Pen(self.pen_cursor(&doc, &sel, to, ev.zoom));
|
||||
if let Some((last, _, out)) = self.tool.pen.as_ref().and_then(|pen| pen.points.last()) {
|
||||
// With Shift the band ends where a click puts the point (#970).
|
||||
let to = if ev.shift { at_45_degrees(*last, to) } else { to };
|
||||
self.tool.overlay.rubber = Some([last.x, last.y, to.x, to.y]);
|
||||
self.tool.overlay.rubber_handle = (out.hypot() > 0.0).then_some([last.x + out.x, last.y + out.y]);
|
||||
}
|
||||
@@ -2214,9 +2223,7 @@ impl Session {
|
||||
if ev.shift
|
||||
&& let Some((last, _, _)) = pen.points.last()
|
||||
{
|
||||
let v = p - *last;
|
||||
let ang = (v.atan2() / (std::f64::consts::PI / 4.0)).round() * std::f64::consts::PI / 4.0;
|
||||
p = *last + Vec2::from_angle(ang) * v.hypot();
|
||||
p = at_45_degrees(*last, p);
|
||||
}
|
||||
pen.points.push((p, Vec2::ZERO, Vec2::ZERO));
|
||||
self.tool.gesture = Gesture::PenDrag { anchor: p };
|
||||
|
||||
Reference in New Issue
Block a user