Rust · 1703 bytes Raw Blame History
1 //! Visual transitions for the greeter
2 //!
3 //! Provides smooth fade effects when starting a session.
4
5 use std::time::{Duration, Instant};
6
7 /// Fade-out transition for session start
8 pub struct FadeOutTransition {
9 start_time: Instant,
10 duration: Duration,
11 }
12
13 impl FadeOutTransition {
14 /// Create a new fade-out transition
15 pub fn new(duration_ms: u64) -> Self {
16 Self {
17 start_time: Instant::now(),
18 duration: Duration::from_millis(duration_ms),
19 }
20 }
21
22 /// Get current opacity (1.0 -> 0.0)
23 pub fn opacity(&self) -> f64 {
24 let elapsed = self.start_time.elapsed();
25 if elapsed >= self.duration {
26 0.0
27 } else {
28 // Ease-out curve for smoother feel
29 let progress = elapsed.as_secs_f64() / self.duration.as_secs_f64();
30 1.0 - ease_out_quad(progress)
31 }
32 }
33
34 /// Check if transition is complete
35 pub fn is_complete(&self) -> bool {
36 self.start_time.elapsed() >= self.duration
37 }
38 }
39
40 /// Quadratic ease-out function for smooth deceleration
41 fn ease_out_quad(t: f64) -> f64 {
42 1.0 - (1.0 - t) * (1.0 - t)
43 }
44
45 /// Render UI elements with fade effect
46 pub fn render_with_fade(
47 ctx: &cairo::Context,
48 opacity: f64,
49 render_fn: impl FnOnce(&cairo::Context) -> anyhow::Result<()>,
50 ) -> anyhow::Result<()> {
51 if opacity >= 1.0 {
52 // Full opacity, render normally
53 render_fn(ctx)?;
54 } else if opacity > 0.0 {
55 // Partial opacity, use group
56 ctx.push_group();
57 render_fn(ctx)?;
58 ctx.pop_group_to_source()?;
59 ctx.paint_with_alpha(opacity)?;
60 }
61 // opacity <= 0.0: don't render anything
62
63 Ok(())
64 }
65