tessera_ui_basic_components/
ripple_state.rs1use std::sync::atomic;
2
3pub struct RippleState {
5 pub is_animating: atomic::AtomicBool,
6 pub start_time: atomic::AtomicU64, pub click_pos_x: atomic::AtomicI32, pub click_pos_y: atomic::AtomicI32, pub is_hovered: atomic::AtomicBool, }
11
12impl Default for RippleState {
13 fn default() -> Self {
14 Self::new()
15 }
16}
17
18impl RippleState {
19 pub fn new() -> Self {
20 Self {
21 is_animating: atomic::AtomicBool::new(false),
22 start_time: atomic::AtomicU64::new(0),
23 click_pos_x: atomic::AtomicI32::new(0),
24 click_pos_y: atomic::AtomicI32::new(0),
25 is_hovered: atomic::AtomicBool::new(false),
26 }
27 }
28
29 pub fn start_animation(&self, click_pos: [f32; 2]) {
30 let now = std::time::SystemTime::now()
31 .duration_since(std::time::UNIX_EPOCH)
32 .unwrap()
33 .as_millis() as u64;
34
35 self.start_time.store(now, atomic::Ordering::SeqCst);
36 self.click_pos_x
37 .store((click_pos[0] * 1000.0) as i32, atomic::Ordering::SeqCst);
38 self.click_pos_y
39 .store((click_pos[1] * 1000.0) as i32, atomic::Ordering::SeqCst);
40 self.is_animating.store(true, atomic::Ordering::SeqCst);
41 }
42
43 pub fn get_animation_progress(&self) -> Option<(f32, [f32; 2])> {
44 let is_animating = self.is_animating.load(atomic::Ordering::SeqCst);
45
46 if !is_animating {
47 return None;
48 }
49
50 let now = std::time::SystemTime::now()
51 .duration_since(std::time::UNIX_EPOCH)
52 .unwrap()
53 .as_millis() as u64;
54 let start = self.start_time.load(atomic::Ordering::SeqCst);
55 let elapsed_ms = now.saturating_sub(start);
56 let progress = (elapsed_ms as f32) / 600.0; if progress >= 1.0 {
59 self.is_animating.store(false, atomic::Ordering::SeqCst);
60 return None;
61 }
62
63 let click_pos = [
64 self.click_pos_x.load(atomic::Ordering::SeqCst) as f32 / 1000.0,
65 self.click_pos_y.load(atomic::Ordering::SeqCst) as f32 / 1000.0,
66 ];
67
68 Some((progress, click_pos))
69 }
70
71 pub fn set_hovered(&self, hovered: bool) {
73 self.is_hovered.store(hovered, atomic::Ordering::SeqCst);
74 }
75
76 pub fn is_hovered(&self) -> bool {
78 self.is_hovered.load(atomic::Ordering::SeqCst)
79 }
80}