use std::time::Duration;
use std::time::SystemTime;
pub trait Interpolation {
fn from_progress(&self, anim_progress: f64) -> f64;
fn calculate(&self, now: SystemTime, start: SystemTime, duration: Duration) -> f64 {
let now_minus_start_ms = {
let (dur, neg) = match now.duration_since(start) {
Ok(d) => (d, false),
Err(err) => (err.duration(), true)
};
let val = dur.as_secs() as f64 * 1000000.0 + dur.subsec_nanos() as f64 / 1000.0;
if neg { -val } else { val }
};
let duration_ms = duration.as_secs() as f64 * 1000000.0 +
duration.subsec_nanos() as f64 / 1000.0;
let anim_progress = now_minus_start_ms / duration_ms;
self.from_progress(anim_progress)
}
#[inline]
fn reverse(self) -> Reversed<Self> where Self: Sized {
Reversed::new(self)
}
#[inline]
fn repeat(self) -> Repeated<Self> where Self: Sized {
Repeated::new(self)
}
#[inline]
fn alternate_repeat(self) -> AlternateRepeated<Self> where Self: Sized {
AlternateRepeated::new(self)
}
}
#[derive(Copy, Clone, Default, Debug)]
pub struct Linear;
impl Interpolation for Linear {
#[inline]
fn from_progress(&self, anim_progress: f64) -> f64 {
if anim_progress >= 1.0 {
1.0
} else if anim_progress <= 0.0 {
0.0
} else {
anim_progress
}
}
}
#[derive(Copy, Clone, Debug)]
pub struct EaseOut {
pub factor: f64,
}
impl EaseOut {
#[inline]
pub fn new(factor: f64) -> EaseOut {
EaseOut {
factor: factor,
}
}
}
impl Default for EaseOut {
#[inline]
fn default() -> EaseOut {
EaseOut { factor: 10.0 }
}
}
impl Interpolation for EaseOut {
#[inline]
fn from_progress(&self, anim_progress: f64) -> f64 {
1.0 - (-anim_progress * self.factor).exp()
}
}
#[derive(Copy, Clone, Debug)]
pub struct Reversed<I> {
inner: I
}
impl<I> Reversed<I> where I: Interpolation {
#[inline]
pub fn new(inner: I) -> Reversed<I> {
Reversed {
inner: inner,
}
}
}
impl<I> Interpolation for Reversed<I> where I: Interpolation {
#[inline]
fn from_progress(&self, anim_progress: f64) -> f64 {
self.inner.from_progress(1.0 - anim_progress)
}
}
#[derive(Copy, Clone, Debug)]
pub struct Repeated<I> {
inner: I
}
impl<I> Repeated<I> where I: Interpolation {
#[inline]
pub fn new(inner: I) -> Repeated<I> {
Repeated {
inner: inner,
}
}
}
impl<I> Interpolation for Repeated<I> where I: Interpolation {
#[inline]
fn from_progress(&self, anim_progress: f64) -> f64 {
let progress = if anim_progress < 0.0 { 1.0 + anim_progress % 1.0 }
else { anim_progress % 1.0 };
self.inner.from_progress(progress)
}
}
#[derive(Copy, Clone, Debug)]
pub struct AlternateRepeated<I> {
inner: I
}
impl<I> AlternateRepeated<I> where I: Interpolation {
#[inline]
pub fn new(inner: I) -> AlternateRepeated<I> {
AlternateRepeated {
inner: inner,
}
}
}
impl<I> Interpolation for AlternateRepeated<I> where I: Interpolation {
#[inline]
fn from_progress(&self, anim_progress: f64) -> f64 {
let progress = 1.0 - ((anim_progress.abs() % 2.0) - 1.0).abs();
self.inner.from_progress(progress)
}
}