1use ranim_core::{
2 animation::Eval,
3 traits::{Interpolatable, Opacity},
4};
5
6pub trait FadingRequirement: Opacity + Interpolatable + Clone {}
9impl<T: Opacity + Interpolatable + Clone> FadingRequirement for T {}
10
11pub trait FadingAnim: FadingRequirement + Sized + 'static {
14 fn fade_in(&mut self) -> FadeIn<Self>;
16 fn fade_out(&mut self) -> FadeOut<Self>;
18}
19
20impl<T: FadingRequirement + Sized + 'static> FadingAnim for T {
21 fn fade_in(&mut self) -> FadeIn<Self> {
22 FadeIn::new(self.clone()).apply_to(self)
23 }
24 fn fade_out(&mut self) -> FadeOut<Self> {
25 FadeOut::new(self.clone()).apply_to(self)
26 }
27}
28
29pub struct FadeIn<T: FadingRequirement> {
37 src: T,
38 dst: T,
39}
40
41impl<T: FadingRequirement> FadeIn<T> {
42 pub fn new(target: T) -> Self {
44 let mut src = target.clone();
45 let dst = target.clone();
46 src.set_opacity(0.0);
47 Self { src, dst }
48 }
49}
50
51impl<T: FadingRequirement> Eval for FadeIn<T> {
52 type Output = T;
53
54 fn eval_alpha(&self, alpha: f64) -> Self::Output {
55 self.src.lerp(&self.dst, alpha)
56 }
57}
58
59pub struct FadeOut<T: FadingRequirement> {
65 src: T,
66 dst: T,
67}
68
69impl<T: FadingRequirement> FadeOut<T> {
70 pub fn new(target: T) -> Self {
72 let src = target.clone();
73 let mut dst = target.clone();
74 dst.set_opacity(0.0);
75 Self { src, dst }
76 }
77}
78
79impl<T: FadingRequirement> Eval for FadeOut<T> {
80 type Output = T;
81
82 fn eval_alpha(&self, alpha: f64) -> Self::Output {
83 self.src.lerp(&self.dst, alpha)
84 }
85}