tuix_core/state/
animation.rs

1#![allow(warnings)]
2
3use crate::entity::Entity;
4use crate::state::storage::dense_storage::DenseStorage;
5pub use crate::state::style::*;
6use crate::{PropSet, State};
7use std::time::{Duration, Instant};
8
9use crate::state::style::Color;
10
11use std::collections::HashMap;
12
13/// An id used to reference stored animations
14#[derive(Debug, Clone, Copy, PartialEq, Hash)]
15pub struct Animation(usize);
16
17impl Animation {
18    pub(crate) fn new(id: usize) -> Self {
19        Self(id)
20    }
21
22    pub fn null() -> Self {
23        Self(std::usize::MAX)
24    }
25
26    pub fn get_id(&self) -> usize {
27        self.0
28    }
29}
30
31impl Default for Animation {
32    fn default() -> Self {
33        Self::null()
34    }
35}
36
37#[derive(Debug, Clone, PartialEq)]
38pub struct Transition {
39    // List of properties affected by transition
40    pub property: String,
41    // Duration of the transition
42    pub duration: f32,
43    // Delay of the transition
44    pub delay: f32,
45}
46
47impl Transition {
48    pub fn new() -> Self {
49        Transition {
50            property: String::new(),
51            duration: 0.0,
52            delay: 0.0,
53        }
54    }
55}
56
57pub trait Interpolator {
58    fn interpolate(start: &Self, end: &Self, t: f32) -> Self;
59}
60
61#[derive(Clone, Debug)]
62pub struct AnimationState<Prop: Interpolator> {
63    // List of property indices that this animation applies to
64    pub indices: Vec<usize>,
65    // The start time of the animation
66    pub start_time: Instant,
67    // The duration of the animation
68    pub duration: Duration,
69    //
70    pub delay: f32,
71    // Animation keyframes (time, value)
72    pub keyframes: Vec<(f32, Prop)>,
73    // The output of the animation
74    pub output: Option<Prop>,
75    // A flag used to check if the animation is finished
76    pub persistent: bool,
77    pub t0: f32,
78    // How far through the animation between 0.0 and 1.0 (used for transitions)
79    pub t: f32,
80
81    pub active: bool,
82
83    // For transitions. The starting rule for this transition.
84    pub from_rule: usize,
85    // For tansitions. The ending rule for this transition.
86    pub to_rule: usize,
87
88    // List of entities connected to this animation (used when animation is removed from active list)
89    pub entities: Vec<Entity>,
90}
91
92impl<Prop> AnimationState<Prop>
93where
94    Prop: Interpolator,
95{
96    pub fn new() -> Self {
97        AnimationState {
98            indices: Vec::new(),
99            start_time: Instant::now(),
100            duration: Duration::new(0, 0),
101            delay: 0.0,
102            keyframes: Vec::new(),
103            output: None,
104            persistent: false,
105            t0: 0.0,
106            t: 0.0,
107            active: false,
108            entities: Vec::new(),
109            from_rule: std::usize::MAX,
110            to_rule: std::usize::MAX,
111        }
112    }
113
114    pub fn with_duration(mut self, duration: Duration) -> Self {
115        self.duration = duration;
116
117        self
118    }
119
120    pub fn with_delay(mut self, delay: Duration) -> Self {
121        self.delay = delay.as_secs_f32() / self.duration.as_secs_f32();
122
123        self
124    }
125
126    pub fn set_delay(&mut self, delay: Duration) -> &mut Self {
127        self.delay = delay.as_secs_f32() / self.duration.as_secs_f32();
128
129        self
130    }
131
132    pub fn with_keyframe(mut self, key: (f32, Prop)) -> Self {
133        self.keyframes.push(key);
134
135        self
136    }
137
138    pub fn interpolate(&mut self, current_time: Instant) -> bool {
139        if current_time > self.start_time + self.duration {
140            return false;
141        }
142        // println!("Animating");
143
144        //let point = self.start_time.elapsed().as_secs_f32() / self.duration.as_secs_f32();
145
146        //let value = Prop::interpolate((0.0,1.0), (&self.keyframes[0].1, &self.keyframes[1].1), point);
147        // use the keyframes to interpolate the value and store the result in output.
148        //let mut pos = Positioning::default();
149
150        //let i = Prop::interpolate(0.0, Prop::default(), 1.0, Prop::default())
151
152        //let i = pos.interpolate();
153
154        true
155    }
156
157    pub fn set_persistent(mut self, flag: bool) -> Self {
158        self.persistent = flag;
159
160        self
161    }
162
163    pub fn get_output(&self) -> Option<&Prop> {
164        self.output.as_ref()
165    }
166}
167
168impl<Prop> Default for AnimationState<Prop>
169where
170    Prop: Interpolator,
171{
172    fn default() -> Self {
173        AnimationState {
174            indices: Vec::new(),
175            start_time: Instant::now(),
176            duration: Duration::new(0, 0),
177            delay: 0.0,
178            keyframes: Vec::new(),
179            output: None,
180            persistent: true,
181            t0: 0.0,
182            t: 0.0,
183            active: false,
184            entities: Vec::new(),
185            from_rule: std::usize::MAX,
186            to_rule: std::usize::MAX,
187        }
188    }
189}
190
191impl Interpolator for Color {
192    fn interpolate(start: &Self, end: &Self, t: f32) -> Self {
193        Color::interpolate(start.clone(), end.clone(), t as f64)
194    }
195}
196
197impl Interpolator for f32 {
198    fn interpolate(start: &Self, end: &Self, t: f32) -> Self {
199        return start + (end - start) * t;
200    }
201}
202
203impl Interpolator for i32 {
204    fn interpolate(start: &Self, end: &Self, t: f32) -> Self {
205        return ((start + (end - start)) as f32 * t).round() as i32;
206    }
207}