2022-07-08 19:48:32 +00:00
|
|
|
use keyframe::EasingFunction;
|
2022-07-10 19:42:42 +00:00
|
|
|
use crate::Color;
|
|
|
|
|
|
|
|
pub trait AnimationLerp<T> {
|
|
|
|
fn lerp(&self, x: f32) -> T;
|
|
|
|
}
|
2022-07-08 19:48:32 +00:00
|
|
|
|
2022-07-09 22:56:19 +00:00
|
|
|
#[derive(Clone)]
|
2022-07-10 19:42:42 +00:00
|
|
|
pub struct Animation<F, T = f32> {
|
2022-07-08 19:48:32 +00:00
|
|
|
time: f32,
|
|
|
|
duration: f32,
|
2022-07-10 14:17:53 +00:00
|
|
|
in_delay: f32,
|
|
|
|
out_delay: f32,
|
2022-07-10 19:42:42 +00:00
|
|
|
from: T,
|
|
|
|
to: T,
|
2022-07-09 02:07:19 +00:00
|
|
|
function: F,
|
2022-07-08 19:48:32 +00:00
|
|
|
direction: bool,
|
|
|
|
}
|
|
|
|
|
2022-07-10 19:42:42 +00:00
|
|
|
impl<F: EasingFunction, T: Copy> Animation<F, T> {
|
|
|
|
pub fn new(function: F, duration: f32, from: T, to: T) -> Self {
|
2022-07-08 19:48:32 +00:00
|
|
|
Self {
|
2022-07-09 02:07:19 +00:00
|
|
|
time: duration,
|
|
|
|
duration,
|
|
|
|
from,
|
|
|
|
to,
|
2022-07-10 14:17:53 +00:00
|
|
|
in_delay: 0.0,
|
|
|
|
out_delay: 0.0,
|
2022-07-09 02:07:19 +00:00
|
|
|
function,
|
|
|
|
direction: false,
|
2022-07-08 19:48:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn update(&mut self, dt: f32) {
|
|
|
|
self.time += dt;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_active(&self) -> bool {
|
2022-07-09 02:07:19 +00:00
|
|
|
self.time < self.duration
|
2022-07-08 19:48:32 +00:00
|
|
|
}
|
|
|
|
|
2022-07-09 02:07:19 +00:00
|
|
|
pub fn ease_in(&mut self) {
|
|
|
|
if !self.direction {
|
|
|
|
self.ease_toggle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn ease_out(&mut self) {
|
|
|
|
if self.direction {
|
|
|
|
self.ease_toggle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn ease_toggle(&mut self) {
|
|
|
|
if self.is_active() {
|
|
|
|
self.time = self.duration - self.time;
|
2022-07-10 14:17:53 +00:00
|
|
|
} else if self.direction {
|
|
|
|
self.time = -self.out_delay;
|
2022-07-09 02:07:19 +00:00
|
|
|
} else {
|
2022-07-10 14:17:53 +00:00
|
|
|
self.time = -self.in_delay;
|
2022-07-09 02:07:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self.direction = !self.direction;
|
2022-07-08 19:48:32 +00:00
|
|
|
}
|
2022-07-10 00:23:13 +00:00
|
|
|
|
2022-07-10 14:17:53 +00:00
|
|
|
pub fn set_in_delay(&mut self, delay: f32) {
|
|
|
|
self.in_delay = delay;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_out_delay(&mut self, delay: f32) {
|
|
|
|
self.out_delay = delay;
|
2022-07-10 00:23:13 +00:00
|
|
|
}
|
2022-07-10 19:42:42 +00:00
|
|
|
|
|
|
|
pub fn clamped(&self) -> Option<T> {
|
|
|
|
if self.is_active() {
|
|
|
|
if self.time <= 0.0 {
|
|
|
|
if self.direction {
|
|
|
|
Some(self.from)
|
|
|
|
} else {
|
|
|
|
Some(self.to)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
} else if self.direction {
|
|
|
|
Some(self.to)
|
|
|
|
} else {
|
|
|
|
Some(self.from)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<F: EasingFunction> AnimationLerp<f32> for Animation<F, f32> {
|
|
|
|
fn lerp(&self, x: f32) -> f32 {
|
|
|
|
(1.0 - x) * self.from + x * self.to
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<F: EasingFunction> AnimationLerp<Color> for Animation<F, Color> {
|
|
|
|
fn lerp(&self, x: f32) -> Color {
|
|
|
|
let from: glam::Vec4 = self.from.into();
|
|
|
|
let to: glam::Vec4 = self.to.into();
|
|
|
|
let lerp = (1.0 - x) * from + x * to;
|
|
|
|
lerp.into()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<F, T> Animation<F, T>
|
|
|
|
where
|
|
|
|
F: EasingFunction,
|
|
|
|
T: Copy,
|
|
|
|
Animation<F, T>: AnimationLerp<T>,
|
|
|
|
{
|
|
|
|
pub fn get(&self) -> T {
|
|
|
|
if let Some(clamped) = self.clamped() {
|
|
|
|
clamped
|
|
|
|
} else {
|
|
|
|
let x = self.time / self.duration;
|
|
|
|
let x = if self.direction { x } else { 1.0 - x };
|
|
|
|
let lerp = self.function.y(x as f64) as f32;
|
|
|
|
self.lerp(lerp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn ease_to(&mut self, to: T) {
|
|
|
|
self.from = self.get();
|
|
|
|
self.to = to;
|
|
|
|
self.time = 0.0;
|
|
|
|
self.direction = true;
|
|
|
|
}
|
2022-07-08 19:48:32 +00:00
|
|
|
}
|