From 60b02545f3c48831381d86f1798c4d1b1b502fcd Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Mon, 4 Mar 2024 16:01:57 +0400 Subject: Move animation to subfolder --- src/animation.rs | 99 ---------------------------------------------------- src/animation/mod.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 99 deletions(-) delete mode 100644 src/animation.rs create mode 100644 src/animation/mod.rs (limited to 'src') diff --git a/src/animation.rs b/src/animation.rs deleted file mode 100644 index bb22b75c..00000000 --- a/src/animation.rs +++ /dev/null @@ -1,99 +0,0 @@ -use std::time::Duration; - -use keyframe::functions::EaseOutCubic; -use keyframe::EasingFunction; -use portable_atomic::{AtomicF64, Ordering}; - -use crate::utils::get_monotonic_time; - -pub static ANIMATION_SLOWDOWN: AtomicF64 = AtomicF64::new(1.); - -#[derive(Debug)] -pub struct Animation { - from: f64, - to: f64, - duration: Duration, - start_time: Duration, - current_time: Duration, - curve: Curve, -} - -#[derive(Debug, Clone, Copy)] -pub enum Curve { - EaseOutCubic, - EaseOutExpo, -} - -impl Animation { - pub fn new( - from: f64, - to: f64, - config: niri_config::Animation, - default: niri_config::Animation, - ) -> Self { - // FIXME: ideally we shouldn't use current time here because animations started within the - // same frame cycle should have the same start time to be synchronized. - let now = get_monotonic_time(); - - let duration_ms = if config.off { - 0 - } else { - config.duration_ms.unwrap_or(default.duration_ms.unwrap()) - }; - let duration = Duration::from_millis(u64::from(duration_ms)) - .mul_f64(ANIMATION_SLOWDOWN.load(Ordering::Relaxed)); - - let curve = Curve::from(config.curve.unwrap_or(default.curve.unwrap())); - - Self { - from, - to, - duration, - start_time: now, - current_time: now, - curve, - } - } - - pub fn set_current_time(&mut self, time: Duration) { - self.current_time = time; - } - - pub fn is_done(&self) -> bool { - self.current_time >= self.start_time + self.duration - } - - pub fn value(&self) -> f64 { - let passed = (self.current_time - self.start_time).as_secs_f64(); - let total = self.duration.as_secs_f64(); - let x = (passed / total).clamp(0., 1.); - self.curve.y(x) * (self.to - self.from) + self.from - } - - pub fn to(&self) -> f64 { - self.to - } - - #[cfg(test)] - pub fn from(&self) -> f64 { - self.from - } -} - -impl Curve { - pub fn y(self, x: f64) -> f64 { - match self { - Curve::EaseOutCubic => EaseOutCubic.y(x), - Curve::EaseOutExpo => 1. - 2f64.powf(-10. * x), - } - } -} - -impl From for Curve { - fn from(value: niri_config::AnimationCurve) -> Self { - match value { - niri_config::AnimationCurve::EaseOutCubic => Curve::EaseOutCubic, - niri_config::AnimationCurve::EaseOutExpo => Curve::EaseOutExpo, - } - } -} diff --git a/src/animation/mod.rs b/src/animation/mod.rs new file mode 100644 index 00000000..bb22b75c --- /dev/null +++ b/src/animation/mod.rs @@ -0,0 +1,99 @@ +use std::time::Duration; + +use keyframe::functions::EaseOutCubic; +use keyframe::EasingFunction; +use portable_atomic::{AtomicF64, Ordering}; + +use crate::utils::get_monotonic_time; + +pub static ANIMATION_SLOWDOWN: AtomicF64 = AtomicF64::new(1.); + +#[derive(Debug)] +pub struct Animation { + from: f64, + to: f64, + duration: Duration, + start_time: Duration, + current_time: Duration, + curve: Curve, +} + +#[derive(Debug, Clone, Copy)] +pub enum Curve { + EaseOutCubic, + EaseOutExpo, +} + +impl Animation { + pub fn new( + from: f64, + to: f64, + config: niri_config::Animation, + default: niri_config::Animation, + ) -> Self { + // FIXME: ideally we shouldn't use current time here because animations started within the + // same frame cycle should have the same start time to be synchronized. + let now = get_monotonic_time(); + + let duration_ms = if config.off { + 0 + } else { + config.duration_ms.unwrap_or(default.duration_ms.unwrap()) + }; + let duration = Duration::from_millis(u64::from(duration_ms)) + .mul_f64(ANIMATION_SLOWDOWN.load(Ordering::Relaxed)); + + let curve = Curve::from(config.curve.unwrap_or(default.curve.unwrap())); + + Self { + from, + to, + duration, + start_time: now, + current_time: now, + curve, + } + } + + pub fn set_current_time(&mut self, time: Duration) { + self.current_time = time; + } + + pub fn is_done(&self) -> bool { + self.current_time >= self.start_time + self.duration + } + + pub fn value(&self) -> f64 { + let passed = (self.current_time - self.start_time).as_secs_f64(); + let total = self.duration.as_secs_f64(); + let x = (passed / total).clamp(0., 1.); + self.curve.y(x) * (self.to - self.from) + self.from + } + + pub fn to(&self) -> f64 { + self.to + } + + #[cfg(test)] + pub fn from(&self) -> f64 { + self.from + } +} + +impl Curve { + pub fn y(self, x: f64) -> f64 { + match self { + Curve::EaseOutCubic => EaseOutCubic.y(x), + Curve::EaseOutExpo => 1. - 2f64.powf(-10. * x), + } + } +} + +impl From for Curve { + fn from(value: niri_config::AnimationCurve) -> Self { + match value { + niri_config::AnimationCurve::EaseOutCubic => Curve::EaseOutCubic, + niri_config::AnimationCurve::EaseOutExpo => Curve::EaseOutExpo, + } + } +} -- cgit