1use crate::style::Style;
7use crate::widget::{Color, Rect};
8
9pub struct Fade {
15 style: *mut Style,
16 start: Color,
17 end: Color,
18 duration_ms: u32,
19 elapsed: u32,
20}
21
22impl Fade {
23 pub fn new(style: &mut Style, start: Color, end: Color, duration_ms: u32) -> Self {
25 Self {
26 style: style as *mut Style,
27 start,
28 end,
29 duration_ms,
30 elapsed: 0,
31 }
32 }
33
34 pub fn tick(&mut self, delta_ms: u32) {
36 self.elapsed = core::cmp::min(self.elapsed + delta_ms, self.duration_ms);
37 let progress = self.elapsed as f32 / self.duration_ms as f32;
38 let lerp = |a: u8, b: u8| a as f32 + (b as f32 - a as f32) * progress;
39 unsafe {
40 (*self.style).bg_color = Color(
41 lerp(self.start.0, self.end.0) as u8,
42 lerp(self.start.1, self.end.1) as u8,
43 lerp(self.start.2, self.end.2) as u8,
44 lerp(self.start.3, self.end.3) as u8,
45 );
46 }
47 }
48
49 pub fn finished(&self) -> bool {
51 self.elapsed >= self.duration_ms
52 }
53}
54
55pub struct Slide {
57 rect: *mut Rect,
58 start: Rect,
59 end: Rect,
60 duration_ms: u32,
61 elapsed: u32,
62}
63
64impl Slide {
65 pub fn new(rect: &mut Rect, start: Rect, end: Rect, duration_ms: u32) -> Self {
67 Self {
68 rect: rect as *mut Rect,
69 start,
70 end,
71 duration_ms,
72 elapsed: 0,
73 }
74 }
75
76 pub fn tick(&mut self, delta_ms: u32) {
78 self.elapsed = core::cmp::min(self.elapsed + delta_ms, self.duration_ms);
79 let p = self.elapsed as f32 / self.duration_ms as f32;
80 let lerp = |a: i32, b: i32| a as f32 + (b as f32 - a as f32) * p;
81 unsafe {
82 *self.rect = Rect {
83 x: lerp(self.start.x, self.end.x) as i32,
84 y: lerp(self.start.y, self.end.y) as i32,
85 width: lerp(self.start.width, self.end.width) as i32,
86 height: lerp(self.start.height, self.end.height) as i32,
87 };
88 }
89 }
90
91 pub fn finished(&self) -> bool {
93 self.elapsed >= self.duration_ms
94 }
95}
96
97pub struct Timeline {
99 fades: alloc::vec::Vec<Fade>,
100 slides: alloc::vec::Vec<Slide>,
101}
102
103impl Timeline {
104 pub fn new() -> Self {
106 Self {
107 fades: alloc::vec::Vec::new(),
108 slides: alloc::vec::Vec::new(),
109 }
110 }
111
112 pub fn add_fade(&mut self, fade: Fade) {
114 self.fades.push(fade);
115 }
116 pub fn add_slide(&mut self, slide: Slide) {
118 self.slides.push(slide);
119 }
120
121 pub fn tick(&mut self, delta_ms: u32) {
123 for fade in &mut self.fades {
124 fade.tick(delta_ms);
125 }
126 for slide in &mut self.slides {
127 slide.tick(delta_ms);
128 }
129 self.fades.retain(|f| !f.finished());
130 self.slides.retain(|s| !s.finished());
131 }
132
133 pub fn is_empty(&self) -> bool {
135 self.fades.is_empty() && self.slides.is_empty()
136 }
137}
138
139impl Default for Timeline {
140 fn default() -> Self {
141 Self::new()
142 }
143}