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 );
45 }
46 }
47
48 pub fn finished(&self) -> bool {
50 self.elapsed >= self.duration_ms
51 }
52}
53
54pub struct Slide {
56 rect: *mut Rect,
57 start: Rect,
58 end: Rect,
59 duration_ms: u32,
60 elapsed: u32,
61}
62
63impl Slide {
64 pub fn new(rect: &mut Rect, start: Rect, end: Rect, duration_ms: u32) -> Self {
66 Self {
67 rect: rect as *mut Rect,
68 start,
69 end,
70 duration_ms,
71 elapsed: 0,
72 }
73 }
74
75 pub fn tick(&mut self, delta_ms: u32) {
77 self.elapsed = core::cmp::min(self.elapsed + delta_ms, self.duration_ms);
78 let p = self.elapsed as f32 / self.duration_ms as f32;
79 let lerp = |a: i32, b: i32| a as f32 + (b as f32 - a as f32) * p;
80 unsafe {
81 *self.rect = Rect {
82 x: lerp(self.start.x, self.end.x) as i32,
83 y: lerp(self.start.y, self.end.y) as i32,
84 width: lerp(self.start.width, self.end.width) as i32,
85 height: lerp(self.start.height, self.end.height) as i32,
86 };
87 }
88 }
89
90 pub fn finished(&self) -> bool {
92 self.elapsed >= self.duration_ms
93 }
94}
95
96pub struct Timeline {
98 fades: alloc::vec::Vec<Fade>,
99 slides: alloc::vec::Vec<Slide>,
100}
101
102impl Timeline {
103 pub fn new() -> Self {
105 Self {
106 fades: alloc::vec::Vec::new(),
107 slides: alloc::vec::Vec::new(),
108 }
109 }
110
111 pub fn add_fade(&mut self, fade: Fade) {
113 self.fades.push(fade);
114 }
115 pub fn add_slide(&mut self, slide: Slide) {
117 self.slides.push(slide);
118 }
119
120 pub fn tick(&mut self, delta_ms: u32) {
122 for fade in &mut self.fades {
123 fade.tick(delta_ms);
124 }
125 for slide in &mut self.slides {
126 slide.tick(delta_ms);
127 }
128 self.fades.retain(|f| !f.finished());
129 self.slides.retain(|s| !s.finished());
130 }
131
132 pub fn is_empty(&self) -> bool {
134 self.fades.is_empty() && self.slides.is_empty()
135 }
136}
137
138impl Default for Timeline {
139 fn default() -> Self {
140 Self::new()
141 }
142}