mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-13 21:17:48 +00:00
Blend: pinning a closed replaced spine gives its end keys points of their own (#6809)
Pinning a closed spine from Replace Spine (a spine edit, Reverse Spine) stored it closed with both end keys on its first point, so moving the first key afterwards landed it on the last. Pinning now opens the spine there as the layout of a moved key does.
This commit is contained in:
@@ -1116,8 +1116,12 @@ pub fn pin_spine(keys: &[Arc<Node>], spec: &BlendSpec) -> Option<(PathData, Vec<
|
||||
&& pinned(spec, keys.len(), first.anchors.len()).is_none()
|
||||
{
|
||||
let mut path = PathData::single(first.clone());
|
||||
let out = spread_anchors(&mut path, keys.len())?;
|
||||
return Some((path, out));
|
||||
let mut out = spread_anchors(&mut path, keys.len())?;
|
||||
// A closed spine's end keys get points of their own, so that once pinned each still
|
||||
// moves only its own end.
|
||||
let mut sp = path.subpaths.into_iter().next()?;
|
||||
open_at_start(&mut sp, &mut out);
|
||||
return Some((PathData::single(sp), out));
|
||||
}
|
||||
let (path, anchors) = blend_spine(keys, spec)?;
|
||||
Some((path, anchors?))
|
||||
|
||||
@@ -484,6 +484,33 @@ fn moving_the_first_key_of_a_closed_replaced_spine_blend_moves_what_is_drawn() {
|
||||
assert!(center(&back[1]).distance(center(&before[1])) < 1e-6);
|
||||
}
|
||||
|
||||
/// #6809 on a closed spine pinned by a spine edit: the end keys get points of their own, so
|
||||
/// moving the first key afterwards still moves only its end.
|
||||
#[test]
|
||||
fn moving_the_first_key_of_a_pinned_closed_spine_blend_moves_what_is_drawn() {
|
||||
let mut s = session();
|
||||
let (a, _, g) = blend(&mut s, json!({"steps": 5}));
|
||||
let square = id_of(&s.execute("path.create", &json!({"d": "M100 100 L300 100 L300 300 L100 300 Z"})).unwrap());
|
||||
sel(&mut s, &[g, square]);
|
||||
s.execute("object.blend.replaceSpine", &json!({})).unwrap();
|
||||
// Dragging a corner away from the keys pins the spine to them.
|
||||
s.execute("object.blend.spine.moveAnchor", &json!({"id": g.0, "anchor": 2, "x": 320, "y": 320})).unwrap();
|
||||
let NodeKind::Blend { spec, .. } = node(&s, g).kind else { panic!() };
|
||||
assert_eq!(spec.key_anchors.len(), 2, "{:?}", spec.key_anchors);
|
||||
let center = |n: &Node| n.geometric_bounds().unwrap().center();
|
||||
let before = steps_of(&s, g);
|
||||
sel(&mut s, &[a]);
|
||||
s.execute("object.move", &json!({"dx": -50, "dy": -40})).unwrap();
|
||||
let key = center(&node(&s, a));
|
||||
assert!(key.distance(Point::new(50.0, 60.0)) < 1e-6, "{key:?}");
|
||||
let after = steps_of(&s, g);
|
||||
assert_eq!(after.len(), before.len());
|
||||
let drawn = center(&after[0]);
|
||||
assert!(drawn.distance(key) < 1e-6, "the key is drawn where it was moved to: {drawn:?}, outline at {key:?}");
|
||||
let last = center(&after[after.len() - 1]);
|
||||
assert!(last.distance(Point::new(100.0, 100.0)) < 1e-6, "the other key stays put: {last:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blend_align_to_path_rotates_steps() {
|
||||
let mut s = session();
|
||||
|
||||
Reference in New Issue
Block a user