Merge pull request #1921 from tylerjenningsw/enhance/keyframe-text-clipboard

Clipboard: export keyframes as After Effects-compatible text
This commit is contained in:
BFlat
2026-10-30 01:22:04 +07:00
committed by GitHub
13 changed files with 1259 additions and 8 deletions
+1
View File
@@ -45,6 +45,7 @@ fn copy(s: &mut Session, _: &Value) -> Result<Value> {
clip.push(KeyClip { layer: lid, path, keys });
}
let n: usize = clip.iter().map(|c| c.keys.len()).sum();
s.state.keyframe_text = crate::keyframe_text::text(&s.project, comp, &s.state.selected_keys, &[]);
s.state.key_clipboard = clip;
s.state.clip_is_keys = true;
Ok(json!(n))
+5
View File
@@ -263,6 +263,7 @@ fn clear_clipboards(s: &mut Session) {
s.state.contents_clipboard.clear();
s.state.link_clipboard = None;
s.state.value_clipboard.clear();
s.state.keyframe_text = None;
s.state.clip_is_keys = false;
}
@@ -329,10 +330,12 @@ fn copy_properties(s: &mut Session) -> Result<Option<Value>> {
}
let mut keys = s.state.selected_keys.clone();
let mut values = vec![];
let mut statics = vec![];
for (lid, uid) in &leaves {
let Some(l) = comp.layer(*lid) else { continue };
let Some(pr) = l.props.find(*uid) else { continue };
if pr.keys.is_empty() {
statics.push((*lid, *uid));
if let Some(path) = l.props.match_path_of(*uid)
&& !values.iter().any(|(p, _)| *p == path)
{
@@ -342,6 +345,7 @@ fn copy_properties(s: &mut Session) -> Result<Option<Value>> {
keys.extend(pr.keys.iter().map(|k| KeyRef { layer: *lid, prop: *uid, time: k.time }));
}
}
let text = crate::keyframe_text::text(&s.project, comp, &keys, &statics);
clear_clipboards(s);
let mut n = 0;
if !keys.is_empty() {
@@ -350,6 +354,7 @@ fn copy_properties(s: &mut Session) -> Result<Option<Value>> {
s.state.selected_keys = selected;
n = r?.as_u64().unwrap_or(0);
}
s.state.keyframe_text = text;
let v = values.len();
s.state.value_clipboard = values;
// Keys alone answer as `keys.copy` does (their count).
+1
View File
@@ -804,6 +804,7 @@ fn copy(s: &mut Session, p: &Value) -> Result<Value> {
}
s.state.clipboard.clear();
s.state.key_clipboard.clear();
s.state.keyframe_text = None;
s.state.contents_clipboard.clear();
s.state.link_clipboard = None;
s.state.clip_is_keys = false;
+1
View File
@@ -289,6 +289,7 @@ fn extract_face(s: &mut Session, p: &Value) -> Result<Value> {
clip.push(crate::KeyClip { layer: lid, path, keys });
}
s.state.key_clipboard = clip;
s.state.keyframe_text = None;
s.state.clip_is_keys = true;
// The same data as text (tab-separated, one row per frame) for other applications.
let mut text = String::from("EffectCraft Face Measurements\n\nFrame\tTime");