ranim_anims/
func.rs

1use ranim_core::animation::{AnimationCell, Eval};
2
3// MARK: Require Trait
4/// The requirement for [`Func`]
5pub trait FuncRequirement: Clone {}
6impl<T: Clone> FuncRequirement for T {}
7
8// MARK: Anim Trait
9/// The methods to create animations for `T` that satisfies [`FuncRequirement`]
10pub trait FuncAnim: FuncRequirement + 'static {
11    /// Create a [`Func`] anim.
12    fn func(&mut self, f: impl Fn(&Self, f64) -> Self + 'static) -> AnimationCell<Self>;
13}
14
15impl<T: FuncRequirement + 'static> FuncAnim for T {
16    fn func(&mut self, f: impl Fn(&Self, f64) -> Self + 'static) -> AnimationCell<Self> {
17        Func::new(self.clone(), f)
18            .into_animation_cell()
19            .apply_to(self)
20    }
21}
22
23// MARK: Impl
24/// An func anim.
25///
26/// This simply use the given func to eval the animation state.
27pub struct Func<T: FuncRequirement> {
28    src: T,
29    #[allow(clippy::type_complexity)]
30    f: Box<dyn Fn(&T, f64) -> T>,
31}
32
33impl<T: FuncRequirement> Func<T> {
34    /// Constructor
35    pub fn new(target: T, f: impl Fn(&T, f64) -> T + 'static) -> Self {
36        Self {
37            src: target,
38            f: Box::new(f),
39        }
40    }
41}
42
43impl<T: FuncRequirement> Eval<T> for Func<T> {
44    fn eval_alpha(&self, alpha: f64) -> T {
45        (self.f)(&self.src, alpha)
46    }
47}