Fix #602: Scale Artwork with Artboard scales the art with a resized artboard

`artboard.setProps {scaleArt: true}` maps the art fully inside a resized
artboard (as Move Artwork with Artboard gathers it) and its artboard guides
from the old rectangle onto the new one, each side by its own ratio, in one
undo step, and returns the ids scaled. Strokes, effects and corners follow
Scale Strokes & Effects and Scale Corners (`strokes`, `corners`), pattern tiles
Transform Pattern Tiles (`patterns`); locked and hidden art follows
`lockedAndHidden` (default: prefs moveLockedWithArtboard). The resolved choices
are journaled, so a replay scales the same objects the same way. A move that
keeps the size scales nothing.

The Artboard tool's `scaleArt` option (saved with `moveArt`) makes handle
drags proportional, as the public help describes, keeps them proportional at
the 1 pt minimum, and leaves the scaled art out of the Smart Guide targets.
Move and Scale Artwork with Artboard are check boxes in the Control bar and
Properties' Edit Artboards; the artboard size fields there and in the
Transform panel pass the option. Translated in the eight catalogs that have
Move Artwork with Artboard. docs/mcp.md and the ROADMAP updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
HT
2026-10-09 11:50:35 +01:00
co-authored by Claude Opus 5.5
parent 133ad87541
commit f2b35fc039
20 changed files with 346 additions and 27 deletions
+8 -1
View File
@@ -96,7 +96,7 @@ pub use vectorcraft_geom as geom;
use serde::{Deserialize, Serialize};
use vectorcraft_color::{Swatch, SwatchGroup};
use vectorcraft_geom::{Point, Rect, Vec2};
use vectorcraft_geom::{Affine, Point, Rect, Vec2};
#[derive(Debug, thiserror::Error, PartialEq)]
pub enum DocError {
@@ -1006,6 +1006,13 @@ impl Document {
*g = g.moved(d);
}
}
/// Map the guides of artboard `id` through `xf`, an axis-aligned scale and move (Scale Artwork
/// with Artboard).
pub fn map_artboard_guides(&mut self, id: u32, xf: Affine) {
for g in self.guides.iter_mut().filter(|g| g.artboard == Some(id)) {
g.pos = if g.vertical { (xf * Point::new(g.pos, 0.0)).x } else { (xf * Point::new(0.0, g.pos)).y };
}
}
/// Copy the guides of artboard `from` onto artboard `to`, `d` away (with a copy of their
/// artboard).
pub fn copy_artboard_guides(&mut self, from: u32, to: u32, d: Vec2) {