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