use crate::{
field::{Fields, FieldsAnimation},
interpolate::InterpolationProgress,
timeline::{Hold, Sequence},
timing::Duration,
};
pub trait Interpolate: Sized {
#[must_use]
fn lerp(&self, other: &Self, progress: f32) -> Self {
Self::interpolate_progress(self, other, InterpolationProgress::new(progress))
}
#[must_use]
fn interpolate(from: &Self, to: &Self, progress: f32) -> Self {
Self::interpolate_progress(from, to, InterpolationProgress::new(progress))
}
#[must_use]
fn extrapolate(from: &Self, to: &Self, progress: f32) -> Self {
Self::interpolate_progress(from, to, InterpolationProgress::extrapolated(progress))
}
#[must_use]
fn interpolate_progress(from: &Self, to: &Self, progress: InterpolationProgress) -> Self;
}
pub trait Animatable: Interpolate + Clone + 'static {}
impl<T: Interpolate + Clone + 'static> Animatable for T {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AnimationState {
Idle,
Running,
Paused,
Completed,
Canceled,
}
pub trait Animation<T: Animatable>: 'static {
#[must_use]
fn value(&self) -> &T;
#[must_use]
fn state(&self) -> AnimationState;
#[must_use]
fn duration(&self) -> Option<Duration> {
None
}
fn tick(&mut self, delta: Duration);
fn advance(&mut self, delta: Duration) -> Duration {
self.tick(delta);
Duration::ZERO
}
fn pause(&mut self);
fn resume(&mut self);
fn cancel(&mut self);
fn seek(&mut self, progress: f32);
fn finish(&mut self);
#[must_use]
fn retarget(&mut self, _target: &T) -> bool {
false
}
#[must_use]
fn is_active(&self) -> bool {
self.state() == AnimationState::Running
}
fn set_rate(&mut self, _rate: f64) {}
#[must_use]
fn rate(mut self, rate: f64) -> Self
where
Self: Sized,
{
self.set_rate(rate);
self
}
#[must_use]
fn into_value(self: Box<Self>) -> T {
self.value().clone()
}
}
pub type BoxAnimation<T> = Box<dyn Animation<T>>;
pub trait AnimationExt<T: Animatable>: Animation<T> + Sized {
#[must_use]
fn boxed(self) -> BoxAnimation<T> {
Box::new(self)
}
#[must_use]
fn then(self, next: impl Animation<T>) -> Sequence<T> {
let initial = self.value().clone();
Sequence::new(initial).then(self).then(next)
}
#[must_use]
fn delay(self, duration: impl Into<Duration>) -> Sequence<T> {
let initial = self.value().clone();
Sequence::new(initial.clone())
.then(Hold::new(initial, duration))
.then(self)
}
}
impl<T: Animatable, A: Animation<T> + Sized> AnimationExt<T> for A {}
#[doc(hidden)]
pub enum DirectAnimation {}
#[doc(hidden)]
pub enum FieldAnimationPlan {}
#[doc(hidden)]
pub enum AnimationFactory {}
mod private {
use super::{Animatable, Animation, AnimationFactory, DirectAnimation, FieldAnimationPlan};
use crate::Fields;
pub trait Sealed<T: Animatable, Kind> {}
impl<T, A> Sealed<T, DirectAnimation> for A
where
T: Animatable,
A: Animation<T>,
{
}
impl<T: Animatable> Sealed<T, FieldAnimationPlan> for Fields<T> {}
impl<T, A, F> Sealed<T, AnimationFactory> for F
where
T: Animatable,
A: Animation<T>,
F: FnOnce(T) -> A,
{
}
}
pub trait IntoMotionAnimation<T: Animatable, Kind>: private::Sealed<T, Kind> {
type Animation: Animation<T>;
#[doc(hidden)]
fn into_motion_animation(self, current: &T) -> Self::Animation;
}
impl<T, A> IntoMotionAnimation<T, DirectAnimation> for A
where
T: Animatable,
A: Animation<T>,
{
type Animation = A;
fn into_motion_animation(self, _current: &T) -> Self::Animation {
self
}
}
impl<T: Animatable> IntoMotionAnimation<T, FieldAnimationPlan> for Fields<T> {
type Animation = FieldsAnimation<T>;
fn into_motion_animation(self, current: &T) -> Self::Animation {
self.build(current)
}
}
impl<T, A, F> IntoMotionAnimation<T, AnimationFactory> for F
where
T: Animatable,
A: Animation<T>,
F: FnOnce(T) -> A,
{
type Animation = A;
fn into_motion_animation(self, current: &T) -> Self::Animation {
self(current.clone())
}
}
impl<Source: ?Sized, T: Animatable> Animation<T> for Box<Source>
where
Source: Animation<T>,
{
fn value(&self) -> &T {
(**self).value()
}
fn state(&self) -> AnimationState {
(**self).state()
}
fn duration(&self) -> Option<Duration> {
(**self).duration()
}
fn tick(&mut self, delta: Duration) {
(**self).tick(delta);
}
fn advance(&mut self, delta: Duration) -> Duration {
(**self).advance(delta)
}
fn pause(&mut self) {
(**self).pause();
}
fn resume(&mut self) {
(**self).resume();
}
fn cancel(&mut self) {
(**self).cancel();
}
fn seek(&mut self, progress: f32) {
(**self).seek(progress);
}
fn finish(&mut self) {
(**self).finish();
}
fn retarget(&mut self, target: &T) -> bool {
(**self).retarget(target)
}
fn is_active(&self) -> bool {
(**self).is_active()
}
fn set_rate(&mut self, rate: f64) {
(**self).set_rate(rate);
}
fn into_value(self: Box<Self>) -> T {
(*self).into_value()
}
}