use ranim_core::{
animation::{AnimationCell, Eval},
traits::{Interpolatable, Opacity},
utils::rate_functions::smooth,
};
pub trait FadingRequirement: Opacity + Interpolatable + Clone {}
impl<T: Opacity + Interpolatable + Clone> FadingRequirement for T {}
pub trait FadingAnim: FadingRequirement + Sized + 'static {
fn fade_in(&mut self) -> AnimationCell<Self>;
fn fade_out(&mut self) -> AnimationCell<Self>;
}
impl<T: FadingRequirement + Sized + 'static> FadingAnim for T {
fn fade_in(&mut self) -> AnimationCell<Self> {
FadeIn::new(self.clone())
.into_animation_cell()
.with_rate_func(smooth)
.apply_to(self)
}
fn fade_out(&mut self) -> AnimationCell<Self> {
FadeOut::new(self.clone())
.into_animation_cell()
.with_rate_func(smooth)
.apply_to(self)
}
}
pub struct FadeIn<T: FadingRequirement> {
src: T,
dst: T,
}
impl<T: FadingRequirement> FadeIn<T> {
pub fn new(target: T) -> Self {
let mut src = target.clone();
let dst = target.clone();
src.set_opacity(0.0);
Self { src, dst }
}
}
impl<T: FadingRequirement> Eval<T> for FadeIn<T> {
fn eval_alpha(&self, alpha: f64) -> T {
self.src.lerp(&self.dst, alpha)
}
}
pub struct FadeOut<T: FadingRequirement> {
src: T,
dst: T,
}
impl<T: FadingRequirement> FadeOut<T> {
pub fn new(target: T) -> Self {
let src = target.clone();
let mut dst = target.clone();
dst.set_opacity(0.0);
Self { src, dst }
}
}
impl<T: FadingRequirement> Eval<T> for FadeOut<T> {
fn eval_alpha(&self, alpha: f64) -> T {
self.src.lerp(&self.dst, alpha)
}
}