mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-30 04:57:54 -06:00
Merge pull request #2306 from marcoarnulfo/fix/lottie-precomp-size
Lottie: size an imported precomp from its precomp layer's w/h when the asset has none
This commit is contained in:
@@ -143,7 +143,9 @@ pub fn import(
|
||||
let Some(id) = s(a, "id") else { continue };
|
||||
if a.get("layers").is_some() {
|
||||
let folder = cx.folder(project);
|
||||
let (aw, ah) = (f(a, "w").map(|v| v as u32).unwrap_or(w), f(a, "h").map(|v| v as u32).unwrap_or(h));
|
||||
let layer = precomp_layer_size(&doc, &assets, id);
|
||||
let aw = f(a, "w").map(|v| v as u32).or(layer.map(|l| l.0)).unwrap_or(w);
|
||||
let ah = f(a, "h").map(|v| v as u32).or(layer.map(|l| l.1)).unwrap_or(h);
|
||||
let arate = f(a, "fr").map(FrameRate::from_f64).unwrap_or(rate);
|
||||
let c = Comp::new(aw, ah, arate, duration);
|
||||
let nm = s(a, "nm").unwrap_or(id).to_string();
|
||||
@@ -242,6 +244,19 @@ pub fn import(
|
||||
Ok(ImportResult { comp: id, items: cx.items, warnings: cx.im.warnings })
|
||||
}
|
||||
|
||||
/// The `w`/`h` of the first precomp layer, in the main comp or in any asset, that shows asset `id`.
|
||||
/// lottie-spec gives a precomposition asset no size: the layer's `w`/`h` are its clipping rect.
|
||||
fn precomp_layer_size(doc: &Json, assets: &[Json], id: &str) -> Option<(u32, u32)> {
|
||||
let lists = doc.get("layers").into_iter().chain(assets.iter().filter_map(|a| a.get("layers")));
|
||||
lists.filter_map(Json::as_array).flatten().find_map(|l| {
|
||||
if l.get("ty").and_then(Json::as_u64) != Some(0) || s(l, "refId") != Some(id) {
|
||||
return None;
|
||||
}
|
||||
let (lw, lh) = f(l, "w").zip(f(l, "h"))?;
|
||||
Some((lw.round().max(1.0) as u32, lh.round().max(1.0) as u32))
|
||||
})
|
||||
}
|
||||
|
||||
fn transform(im: &Im, ks: &Json, tr: &mut PropGroup, next: &mut u64) {
|
||||
let set = |tr: &mut PropGroup, m: &str, j: Option<&Json>, conv: &dyn Fn(&Json) -> Option<Value>| {
|
||||
if let (Some(j), Some(p)) = (j, tr.get_mut(m)) {
|
||||
|
||||
@@ -527,6 +527,19 @@ fn precomp_with_time_remap() {
|
||||
compare_renders(&p, cid, &q, nc, 2.0 / 255.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn precomp_size_comes_from_the_layer_when_the_asset_has_none() {
|
||||
// lottie-spec: a precomposition asset has no `w`/`h`; the precomp layer carries them.
|
||||
let doc = json!({"w": 200, "h": 120, "fr": 30, "ip": 0, "op": 30,
|
||||
"assets": [{"id": "c", "layers": []}],
|
||||
"layers": [{"ty": 0, "ind": 1, "refId": "c", "w": 50, "h": 40, "ip": 0, "op": 30, "st": 0, "ks": {}}]});
|
||||
let mut q = Project::default();
|
||||
let nc = import(&mut q, doc.to_string().as_bytes(), "Imported", "", &mut |_| None).unwrap().comp;
|
||||
let LayerSource::Comp { item } = q.comp(nc).unwrap().layers[0].source else { panic!("not a precomp") };
|
||||
let pc = q.comp(item).unwrap();
|
||||
assert_eq!((pc.width, pc.height), (50, 40));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn text_layers_roundtrip_as_text_and_as_shapes() {
|
||||
let (mut p, cid) = setup();
|
||||
|
||||
Reference in New Issue
Block a user