mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-29 12:17:14 -06:00
Fix Shift-scaling a corner handle along a single axis
Fixes #4262 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Opus 5.5
parent
7a2683d6d0
commit
8b4ebf50be
@@ -91,9 +91,11 @@ pub fn scale_for_drag(r: Rect, handle: Handle, p: Point, proportional: bool, fro
|
||||
let mut sy = if ay && d0.y.abs() > 1e-9 { d1.y / d0.y } else { 1.0 };
|
||||
if proportional {
|
||||
if handle.is_corner() {
|
||||
let s = if sx.abs() > sy.abs() { sx } else { sy };
|
||||
sx = s.abs() * sx.signum();
|
||||
sy = s.abs() * sy.signum();
|
||||
// Follow the axis the pointer moved further along (a drag along one axis must still
|
||||
// resize), and mirror both axes together when it crosses the origin.
|
||||
let s = if (sx - 1.0).abs() >= (sy - 1.0).abs() { sx } else { sy };
|
||||
sx = s;
|
||||
sy = s;
|
||||
} else if ax {
|
||||
sy = sx.abs();
|
||||
} else {
|
||||
@@ -151,6 +153,25 @@ mod tests {
|
||||
assert_eq!(a.transform_rect_bbox(R), Rect::new(0.0, 0.0, 200.0, 100.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn proportional_corner_follows_a_drag_along_one_axis() {
|
||||
let scale = |p: Point, from_center: bool| {
|
||||
let a = scale_for_drag(R, Handle::BottomRight, p, true, from_center).as_coeffs();
|
||||
(a[0], a[3])
|
||||
};
|
||||
for from_center in [false, true] {
|
||||
let o = if from_center { R.center() } else { Point::new(0.0, 0.0) };
|
||||
let (hx, hy) = (100.0 - o.x, 50.0 - o.y);
|
||||
// Horizontal drag, then vertical drag: the size follows the pointer, uniformly.
|
||||
for (t, want) in [(0.5, 0.5), (0.25, 0.25), (-0.5, -0.5), (-1.0, -1.0)] {
|
||||
for p in [Point::new(o.x + hx * t, 50.0), Point::new(100.0, o.y + hy * t)] {
|
||||
let (sx, sy) = scale(p, from_center);
|
||||
assert!((sx - want).abs() < 1e-9 && (sy - want).abs() < 1e-9, "{p:?} center={from_center}: got ({sx}, {sy}), want {want}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_side_and_center() {
|
||||
let a = scale_for_drag(R, Handle::Right, Point::new(150.0, 999.0), false, false);
|
||||
|
||||
Reference in New Issue
Block a user