Skip to main content

ferroui_base/animation/transitions/
double_transition.rs

1use crate::animation::animators::DoubleAnimator;
2use crate::animation::easings::{Easing, LinearEasing};
3use crate::animation::{AnimatorDrivenTransition, Transition, TransitionBase, TransitionObservableBase};
4use crate::ferro_transition_class;
5use crate::reactive::IObservable;
6use std::rc::Rc;
7
8ferro_transition_class!(
9    /// Transition class that handles properties with `f64` types.
10    ///
11    /// A change from or to a value that is not a number (`NaN`, the automatic size of `Width`
12    /// and `Height`) is not interpolated: an interpolation with `NaN` is `NaN` for the whole
13    /// duration, so the new value is taken at once, when the delay has passed.
14    DoubleTransition: f64
15);
16
17impl Transition<f64> for DoubleTransition {
18    fn do_transition(
19        this: &Self,
20        progress: Rc<dyn IObservable<f64>>,
21        old_value: f64,
22        new_value: f64,
23    ) -> Rc<dyn IObservable<f64>> {
24        // Deviation (DEVIATIONS.md, Animation): upstream interpolates NaN, which is NaN for the
25        // whole duration; the value that is not a number is taken at once.
26        if old_value.is_nan() || new_value.is_nan() {
27            let immediate = this.delay() == crate::animation::TimeSpan::ZERO;
28            return TransitionObservableBase::new(progress, Easing::new(LinearEasing::new()), move |progress| {
29                if immediate || progress > 0.0 {
30                    new_value
31                } else {
32                    old_value
33                }
34            });
35        }
36        AnimatorDrivenTransition::transition::<DoubleAnimator>(this.easing(), progress, old_value, new_value)
37    }
38}