mirror of
https://github.com/storytold/filmcraft.git
synced 2026-10-24 10:10:05 -06:00
Graphics: New Layer from File anchors the picture at its own centre
graphics.newFromFile resolved the Motion anchor with the sequence frame size instead of the imported picture's size, so a picture smaller than the frame got its anchor at the frame centre (e.g. 960,540 for a 4x2 image). Setting Motion ▸ Position then moved the wrong point and the picture landed far from where it was asked to go. place_video_clip now resolves auto points with the source's own size (Project::source_size), falling back to the frame size. The new-layer-from-file test checks the anchor is the picture's centre; it fails before this change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
86f3375775
commit
57069293fb
@@ -124,13 +124,15 @@ pub(crate) fn place_video_clip(
|
||||
(q.settings.width, q.settings.height, q.settings.frame_rate)
|
||||
};
|
||||
let (src, dur) = source(pr, (w, h, rate));
|
||||
// an imported picture (`graphics.newFromFile`) keeps its own size: centre its anchor in it
|
||||
let src_size = pr.source_size(src).unwrap_or((w, h));
|
||||
let t = rate.snap(t);
|
||||
let dur = dur.max(rate.frame_duration());
|
||||
let mut ti = pr.make_track_item(src, TrackKind::Video, t, TimeRange::new(Tick::ZERO, dur), rate).ok_or_else(|| bad("graphics.newText", "bad item"))?;
|
||||
ti.name = name;
|
||||
ti.effects.extend(extra);
|
||||
for e in &mut ti.effects {
|
||||
filmcraft_project::resolve_auto_points(e, (w, h), (w, h));
|
||||
filmcraft_project::resolve_auto_points(e, (w, h), src_size);
|
||||
}
|
||||
let id = ti.id;
|
||||
let track_id = filmcraft_project::TrackId(pr.alloc_id());
|
||||
|
||||
@@ -369,6 +369,9 @@ fn new_layer_from_file_places_the_image_above() {
|
||||
assert_eq!(it.start, q.settings.frame_rate.snap(t));
|
||||
let ti = q.video_tracks.iter().position(|tr| tr.id == tid).unwrap();
|
||||
assert!(q.video_tracks[..ti].iter().any(|tr| tr.item_at(t).is_some()), "above the footage");
|
||||
// the anchor is the picture's centre, not the frame's, so `position` places the picture
|
||||
let anchor = it.effect("motion").unwrap().vec2_at("anchor", Tick::ZERO);
|
||||
assert_eq!((anchor.x, anchor.y), (w as f64 / 2.0, h as f64 / 2.0));
|
||||
assert_eq!(s.state.selection, vec![clip]);
|
||||
assert!(s.execute("graphics.newFromFile", json!({})).is_err());
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
|
||||
Reference in New Issue
Block a user