use std::time::{Duration, Instant};
pub mod easing {
use std::f64::consts::PI;
#[allow(unused)]
pub fn cubic_fly_hover_out(t: f64) -> f64 {
let t_in = 500.0 / 4500.0;
let t_out = 4000.0 / 4500.0;
if t <= t_in {
let u = t / t_in;
let inv = 1.0 - u;
1.0 - inv * inv * inv
} else if t <= t_out {
1.0
} else {
let u = (t - t_out) / (1.0 - t_out);
1.0 - u * u * u
}
}
#[allow(unused)]
pub fn linear(t: f64) -> f64 {
t
}
#[allow(unused)]
pub fn quad_in(t: f64) -> f64 {
t * t
}
#[allow(unused)]
pub fn quad_out(t: f64) -> f64 {
t * (2.0 - t)
}
#[allow(unused)]
pub fn quad_in_out(t: f64) -> f64 {
if t < 0.5 {
2.0 * t * t
} else {
-1.0 + (4.0 - 2.0 * t) * t
}
}
#[allow(unused)]
pub fn sine_in(t: f64) -> f64 {
1.0 - (t * PI / 2.0).cos()
}
#[allow(unused)]
pub fn sine_out(t: f64) -> f64 {
(t * PI / 2.0).sin()
}
#[allow(unused)]
pub fn sine_in_out(t: f64) -> f64 {
-0.5 * ((t * PI).cos() - 1.0)
}
#[allow(unused)]
pub fn cubic_in_out(t: f64) -> f64 {
if t < 0.5 {
4.0 * t * t * t
} else {
let f = 2.0 * t - 2.0;
0.5 * f * f * f + 1.0
}
}
}
pub struct StoryBoard {
beginning: Instant,
start: f64,
end: f64,
duration: f64, conv: fn(f64) -> f64, r#loop: bool,
}
impl StoryBoard {
pub fn init(start: f64, end: f64, duration: f64, r#loop: bool, f: fn(f64) -> f64) -> Self {
Self {
beginning: Instant::now(),
start,
end,
duration,
conv: f,
r#loop,
}
}
pub fn set_loop(&mut self, r#loop: bool) {
self.r#loop = r#loop;
}
pub fn restart(&mut self) {
self.beginning = Instant::now();
}
pub fn reverse(&mut self) {
(self.start, self.end) = (self.end, self.start)
}
pub fn get_progress(&self) -> f64 {
if self.duration <= 0.0 {
return 1.0;
}
let pasted = Instant::now().duration_since(self.beginning).as_millis() as f64;
let ratio = pasted / self.duration;
if self.r#loop {
ratio.rem_euclid(1.0)
} else {
ratio.clamp(0.0, 1.0)
}
}
pub fn seek(&mut self, progress: f64) {
if self.duration <= 0.0 {
return;
}
let target_progress = if self.r#loop {
progress.rem_euclid(1.0)
} else {
progress.clamp(0.0, 1.0)
};
let pasted_ms = target_progress * self.duration;
self.beginning = Instant::now() - Duration::from_secs_f64(pasted_ms / 1000.0);
}
}
impl From<&StoryBoard> for f64 {
fn from(value: &StoryBoard) -> Self {
if value.duration <= 0.0 {
return value.end;
}
let r = value.get_progress();
let x = (value.conv)(r);
x * (value.end - value.start) + value.start
}
}