mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-30 20:58:00 -06:00
Distortion tools (Width, Liquify, Puppet Warp, Perspective Grid), Patterns + Repeat, colour management (CMS, proofing, separations), Preferences/Shortcuts/Workspaces; original brand mark; fix filter panic in thumbnails; README demo scenes
- New original DrawCraft mark (gradient + pen nib) replaces the two-letter badge
- render: thumbnails and pattern tiles use a single-threaded context (vello's default is
multithreaded and panics on filters); per-item raster effects detected
- Type tool state no longer leaks across documents
- ui.set {status} for clean screenshots
- README: new hero, feature shots, Made in DrawCraft gallery; examples/neon-drive, ribbons,
feature-sheet; ASSETS.md updated; heading renamed to Crafting Apps
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
05f5bed1ad
commit
acb2566d89
@@ -72,7 +72,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
[],
|
||||
None,
|
||||
"{ids?, colors?: [color]} colours that can't be printed in the working CMYK (selection, or the whole document when nothing is selected) → {checked, outOfGamut: [{hex, deltaE, count}]}",
|
||||
always,
|
||||
has_doc,
|
||||
gamut_check
|
||||
),
|
||||
cmd!(
|
||||
@@ -410,7 +410,10 @@ fn plates_json(s: &Session) -> Value {
|
||||
fn separations(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
const C: &str = "view.separationsPreview";
|
||||
let mut v = proof::view();
|
||||
let all: Vec<String> = s.active().map(|d| proof::plates(&d.doc).into_iter().map(|p| p.name).collect()).unwrap_or_else(|| cms::PROCESS_PLATES.iter().map(|s| s.to_string()).collect());
|
||||
let all: Vec<String> = s
|
||||
.active()
|
||||
.map(|d| proof::plates(&d.doc).into_iter().map(|p| p.name).collect())
|
||||
.unwrap_or_else(|| cms::PROCESS_PLATES.iter().map(|s| s.to_string()).collect());
|
||||
let check = |n: &str| if all.iter().any(|a| a == n) { Ok(n.to_string()) } else { Err(bad(C, format!("unknown plate `{n}`"))) };
|
||||
if let Some(on) = p.get("on").and_then(Value::as_bool) {
|
||||
v.separations = if on { Some(v.separations.take().unwrap_or_else(|| all.clone())) } else { None };
|
||||
|
||||
@@ -251,7 +251,9 @@ fn liquify(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let sweep = dab_pts.iter().map(|c| prm.brush_bounds(*c)).reduce(|a, b| a.union(b)).unwrap();
|
||||
let mut all = vec![];
|
||||
doc.walk(|n| {
|
||||
if matches!(n.kind, NodeKind::Path { guide: false, .. }) && n.geometric_bounds().is_some_and(|b| b.inflate(1e-6, 1e-6).intersect(sweep).area() > 0.0) {
|
||||
if matches!(n.kind, NodeKind::Path { guide: false, .. })
|
||||
&& n.geometric_bounds().is_some_and(|b| b.inflate(1e-6, 1e-6).intersect(sweep).area() > 0.0)
|
||||
{
|
||||
all.push(n.id);
|
||||
}
|
||||
});
|
||||
@@ -345,7 +347,11 @@ fn grid_set(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
|
||||
fn grid_preset(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let kind = p.get("kind").and_then(Value::as_u64).filter(|k| (1..=3).contains(k)).ok_or_else(|| bad("perspective.grid.preset", "kind must be 1, 2 or 3"))? as u8;
|
||||
let kind = p
|
||||
.get("kind")
|
||||
.and_then(Value::as_u64)
|
||||
.filter(|k| (1..=3).contains(k))
|
||||
.ok_or_else(|| bad("perspective.grid.preset", "kind must be 1, 2 or 3"))? as u8;
|
||||
let old = grid_of(&s.doc()?.doc);
|
||||
let ab = s.doc()?.doc.artboards.first().map(|a| a.rect).ok_or_else(|| EngineError::Other("no artboard".into()))?;
|
||||
let g = PerspectiveGrid { attached: old.attached, ..PerspectiveGrid::preset(kind, ab) };
|
||||
|
||||
@@ -16,10 +16,10 @@ mod live;
|
||||
pub(crate) mod menucmds;
|
||||
mod object;
|
||||
mod paint;
|
||||
mod patterncmds;
|
||||
mod panelcmds;
|
||||
mod path;
|
||||
mod pathops;
|
||||
mod patterncmds;
|
||||
pub mod prefscmds;
|
||||
mod recolor;
|
||||
mod select;
|
||||
|
||||
Reference in New Issue
Block a user