mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-12 05:12:21 +00:00
Settings: fit tools move the playhead to the first frame inside the span
The work area need not sit on frames (a typed start, a frame-rate change), so rounding its start to the nearest frame could land before the new layer's in-point. show_span now rounds up to the first frame in the span and moves nothing when the span holds no frame.
This commit is contained in:
1 parent
34086899ad
commit
1991ad5d56
2 files changed
+30
-2
No files matched your search
@@ -31,12 +31,19 @@ pub(crate) fn fit_span(l: &mut Layer, span: Option<(Tick, Tick)>) {
|
||||
}
|
||||
|
||||
/// Tools draw on the layer they create: when it was fitted to a span the playhead is outside,
|
||||
/// move `comp`'s playhead to the span's start so the new layer shows. The layer's timing is kept.
|
||||
/// move `comp`'s playhead to the first frame in the span so the new layer shows. The layer's timing
|
||||
/// is kept. The work area need not sit on frames (a typed start, a frame-rate change), so the
|
||||
/// frame is rounded up from the start, not to the nearest; a span holding no frame moves nothing.
|
||||
pub(crate) fn show_span(s: &mut Session, comp: ItemId, span: Option<(Tick, Tick)>) {
|
||||
let Some(fr) = s.project.comp(comp).map(|c| c.frame_rate) else { return };
|
||||
if let Some((start, end)) = span
|
||||
&& !(start..end).contains(&s.time_of(comp))
|
||||
{
|
||||
s.set_time_of(comp, start);
|
||||
let first = fr.snap(start);
|
||||
let first = if first < start { fr.tick_of(fr.frame_at(start).saturating_add(1)) } else { first };
|
||||
if first < end {
|
||||
s.set_time_of(comp, first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -449,6 +449,27 @@ fn fitted_layers_in_another_comp_move_that_comps_playhead() {
|
||||
}
|
||||
}
|
||||
|
||||
/// A work area off the frame grid (set at 25 fps, then the comp went to 30 fps): the playhead
|
||||
/// goes to the first frame inside it, not the nearest frame before its start.
|
||||
#[test]
|
||||
fn fitted_layers_off_the_frame_grid_move_the_playhead_inside_them() {
|
||||
let mut s = Session::default();
|
||||
s.execute("comp.new", json!({"name": "Grid", "duration": 2, "frameRate": 25})).unwrap();
|
||||
s.execute("prefs.set", json!({"key": "general.fitNewLayersToWorkArea", "value": true})).unwrap();
|
||||
s.execute("comp.workArea", json!({"start": 0.04, "end": 0.08})).unwrap();
|
||||
s.execute("comp.settings", json!({"frameRate": 30})).unwrap();
|
||||
for (cmd, p) in [("layer.newText", json!({"text": "a", "edit": true})), ("shape.newPath", json!({"vertices": [[0, 0], [10, 0], [10, 10]]}))] {
|
||||
s.set_time(effectcraft_time::Tick::from_seconds_f64(1.0));
|
||||
s.state.selected_layers.clear();
|
||||
s.state.text_edit = None;
|
||||
s.execute(cmd, p).unwrap();
|
||||
let l = &s.active_comp().unwrap().layers[0];
|
||||
let t = s.time();
|
||||
assert!(l.in_point <= t && t < l.out_point, "{cmd}: {t:?} in {:?}..{:?}", l.in_point, l.out_point);
|
||||
assert_eq!(t, effectcraft_time::Tick::from_seconds_f64(2.0 / 30.0), "{cmd}: the first frame inside");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_spatial_interpolation_linear() {
|
||||
let mut s = session_with_comp();
|
||||
|
||||
Reference in new issue
Block a user