Skip to main content

ferroui_base/rendering/composition/animations/
key_frames.rs

1use crate::animation::easings::IEasing;
2use crate::rendering::composition::expressions::Expression;
3use std::any::Any;
4use std::rc::Rc;
5
6/// Collection of composition animation key frames
7pub struct KeyFrames<T> {
8    items: Vec<KeyFrame<T>>,
9}
10
11impl<T> Default for KeyFrames<T> {
12    fn default() -> Self {
13        Self { items: Vec::new() }
14    }
15}
16
17impl<T: Copy + Default + 'static> KeyFrames<T> {
18    pub fn new() -> Self {
19        Self::default()
20    }
21
22    pub fn count(&self) -> usize {
23        self.items.len()
24    }
25
26    pub fn items(&self) -> &[KeyFrame<T>] {
27        &self.items
28    }
29
30    fn validate(&self, key: f32) {
31        if key < 0.0 || key > 1.0 {
32            panic!("Key frame key");
33        }
34        if let Some(last) = self.items.last() {
35            if last.normalized_progress_key > key {
36                panic!("Key frame key {key} is less than the previous one");
37            }
38        }
39    }
40
41    pub fn insert_expression_key_frame(&mut self, normalized_progress_key: f32, value: &str, easing_function: Rc<dyn IEasing>) {
42        self.validate(normalized_progress_key);
43        let expression = match Expression::parse(value) {
44            Ok(expression) => expression,
45            Err(error) => panic!("{error}"),
46        };
47        self.items.push(KeyFrame {
48            normalized_progress_key,
49            value: T::default(),
50            expression: Some(std::sync::Arc::new(expression)),
51            easing_function,
52        });
53    }
54
55    pub fn insert(&mut self, normalized_progress_key: f32, value: T, easing_function: Rc<dyn IEasing>) {
56        self.validate(normalized_progress_key);
57        self.items.push(KeyFrame { normalized_progress_key, value, expression: None, easing_function });
58    }
59
60    pub fn snapshot(&self) -> Vec<ServerKeyFrame<T>> {
61        self.items
62            .iter()
63            .map(|f| ServerKeyFrame {
64                expression: f.expression.clone(),
65                value: f.value,
66                easing_function: Some(f.easing_function.to_shared()),
67                key: f.normalized_progress_key,
68            })
69            .collect()
70    }
71}
72
73/// Composition animation key frame
74#[derive(Clone)]
75pub struct KeyFrame<T> {
76    pub normalized_progress_key: f32,
77    pub value: T,
78    /// The expression of an expression key frame (`null` upstream for a
79    /// value key frame).
80    pub expression: Option<std::sync::Arc<Expression>>,
81    pub easing_function: Rc<dyn IEasing>,
82}
83
84/// Server-side composition animation key frame
85#[derive(Clone, Default)]
86pub struct ServerKeyFrame<T> {
87    pub value: T,
88    pub expression: Option<std::sync::Arc<Expression>>,
89    /// Always set on a key frame of a snapshot; `None` only on the frame an
90    /// instance builds for the starting value, whose easing is never used.
91    /// The easing in the form the render thread evaluates.
92    pub easing_function: Option<std::sync::Arc<crate::animation::easings::SharedEasing>>,
93    pub key: f32,
94}
95
96/// The key frames of a key frame animation, whatever their value type.
97pub trait IKeyFrames: Any {
98    fn insert_expression_key_frame(&mut self, normalized_progress_key: f32, value: &str, easing_function: Rc<dyn IEasing>);
99
100    /// The number of key frames.
101    fn key_frame_count(&self) -> usize;
102
103    fn as_any(&self) -> &dyn Any;
104
105    fn as_any_mut(&mut self) -> &mut dyn Any;
106}
107
108impl<T: Copy + Default + 'static> IKeyFrames for KeyFrames<T> {
109    fn insert_expression_key_frame(&mut self, normalized_progress_key: f32, value: &str, easing_function: Rc<dyn IEasing>) {
110        KeyFrames::insert_expression_key_frame(self, normalized_progress_key, value, easing_function)
111    }
112
113    fn key_frame_count(&self) -> usize {
114        self.count()
115    }
116
117    fn as_any(&self) -> &dyn Any {
118        self
119    }
120
121    fn as_any_mut(&mut self) -> &mut dyn Any {
122        self
123    }
124}