diff --git a/crates/lottie/src/shapes.rs b/crates/lottie/src/shapes.rs index 1283a2497..990a0f28b 100644 --- a/crates/lottie/src/shapes.rs +++ b/crates/lottie/src/shapes.rs @@ -3,8 +3,8 @@ use effectcraft_color::BlendMode; use effectcraft_keyframe::{Gradient, ShapePath, Value}; -use effectcraft_project::build::{self, Ids}; -use effectcraft_project::{Node, PropGroup}; +use effectcraft_project::build::{self, EXTRA_DASHES, Ids}; +use effectcraft_project::{Node, ParamUi, PropGroup}; use serde_json::{Map, Value as Json, json}; use crate::anim::{self, Ex, Im, export_prop, import_prop}; @@ -356,7 +356,7 @@ fn import_blend(j: &Json, g: &mut PropGroup) { } } -fn import_stroke(im: &Im, j: &Json, g: &mut PropGroup) { +fn import_stroke(im: &Im, ids: &mut Ids, j: &Json, g: &mut PropGroup) { set(im, g, "width", j.get("w"), &anim::to_scalar); if let Some(lc) = int(j, "lc") { set_enum(g, "cap", lc.saturating_sub(1).clamp(0, 2) as u32); @@ -374,17 +374,32 @@ fn import_stroke(im: &Im, j: &Json, g: &mut PropGroup) { if let Some(list) = j.get("d").and_then(Json::as_array) && let Some(d) = g.sub_mut("dashes") { - let mut seen_dash = false; + // The n-th `d` and `g` are the n-th Dash/Gap pair; the extra pairs are created as the Dashes "+" does. + let (mut dashes, mut gaps) = (0, 0); for e in list { - let m = match e.get("n").and_then(Json::as_str) { - Some("d") if !seen_dash => { - seen_dash = true; - "dash" + let (n, pair) = match e.get("n").and_then(Json::as_str) { + Some("d") => (&mut dashes, 0), + Some("g") => (&mut gaps, 1), + Some("o") => { + set(im, d, "offset", e.get("v"), &anim::to_scalar); + continue; } - Some("g") => "gap", - Some("o") => "offset", _ => continue, }; + let k = *n; + *n += 1; + let m = match k { + 0 => ["dash", "gap"][pair], + _ => { + let Some(&(dm, gm)) = EXTRA_DASHES.get(k - 1) else { continue }; + if d.get(dm).is_none() { + let at = d.children.iter().position(|c| c.match_id() == "offset").unwrap_or(d.children.len()); + d.children.insert(at, ids.prop(gm, &format!("Gap {}", k + 1), Value::Scalar(0.0)).with_ui(ParamUi::Pixels).into()); + d.children.insert(at, ids.prop(dm, &format!("Dash {}", k + 1), Value::Scalar(0.0)).with_ui(ParamUi::Pixels).into()); + } + [dm, gm][pair] + } + }; set(im, d, m, e.get("v"), &anim::to_scalar); } } @@ -474,7 +489,7 @@ pub(crate) fn import_items(im: &mut Im, ids: &mut Ids, items: &[Json]) -> Vec Vec