use crate::{
core::{animation::Primitive, easing, Animatable},
Animation, Timeline, DEFAULT_ANIMATION_DURATION,
};
use std::{fmt, time::Duration};
#[derive(Debug, Clone, Copy)]
pub enum RepeatBehavior {
Count(f32),
Forever,
}
impl Default for RepeatBehavior {
#[inline]
fn default() -> Self {
RepeatBehavior::Count(1.0)
}
}
pub struct Options<T: Animatable> {
pub(crate) from: T,
pub(crate) to: T,
pub(crate) auto_reverse: bool,
pub(crate) skip: Option<Duration>,
pub(crate) delay: Option<Duration>,
pub(crate) duration: Duration,
pub(crate) repeat: RepeatBehavior,
pub(crate) easing: Box<dyn easing::Function>,
}
impl<T: Animatable + Default> Default for Options<T> {
fn default() -> Self {
Self {
from: Default::default(),
to: Default::default(),
auto_reverse: false,
skip: None,
delay: None,
duration: DEFAULT_ANIMATION_DURATION,
repeat: Default::default(),
easing: Box::new(easing::linear()),
}
}
}
impl<T: Animatable> Options<T> {
#[inline]
pub fn new(from: T, to: T) -> Self {
Options {
from,
to,
auto_reverse: false,
skip: None,
delay: None,
duration: DEFAULT_ANIMATION_DURATION,
repeat: Default::default(),
easing: Box::new(easing::cubic_ease()),
}
}
#[inline]
pub fn from(mut self, value: T) -> Self {
self.from = value;
self
}
#[inline]
pub fn to(mut self, value: T) -> Self {
self.to = value;
self
}
#[inline]
pub fn auto_reverse(mut self, auto_reverse: bool) -> Self {
self.auto_reverse = auto_reverse;
self
}
#[deprecated()]
#[inline]
pub fn begin_time(self, begin_time: Duration) -> Self {
self.skip(begin_time)
}
#[inline]
pub fn skip(mut self, skip: Duration) -> Self {
self.skip = Some(skip);
self
}
#[inline]
pub fn delay(mut self, delay: Duration) -> Self {
self.delay = Some(delay);
self
}
#[inline]
pub fn duration(mut self, duration: Duration) -> Self {
self.duration = duration;
self
}
#[inline]
pub fn repeat(mut self, behavior: RepeatBehavior) -> Self {
if let RepeatBehavior::Count(count) = behavior {
assert!(count >= 0.0);
}
self.repeat = behavior;
self
}
#[inline]
pub fn forever(self) -> Self {
self.cycle()
}
pub fn cycle(mut self) -> Self {
self.repeat = RepeatBehavior::Forever;
self
}
#[inline]
pub fn times(mut self, count: f32) -> Self {
assert!(count >= 0.0);
self.repeat = RepeatBehavior::Count(count);
self
}
#[inline]
pub fn easing(mut self, func: impl easing::Function + Clone + 'static) -> Self {
self.easing = Box::new(func);
self
}
#[inline]
pub fn build(self) -> impl Animation<Item = T> + Clone {
Primitive::new(self)
}
}
impl<T: Animatable + 'static> Options<T> {
#[inline]
pub fn begin_animation(self) -> Timeline<T> {
let mut timeline: Timeline<_> = self.into();
timeline.begin();
timeline
}
}
impl<T: Animatable + fmt::Debug> fmt::Debug for Options<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Options")
.field("from", &self.from)
.field("to", &self.to)
.field("auto_reverse", &self.auto_reverse)
.field("begin_time", &self.skip)
.field("duration", &self.duration)
.field("repeat", &self.repeat)
.field("easing", &"???")
.finish()
}
}
impl<T: Animatable> Clone for Options<T> {
#[inline]
fn clone(&self) -> Self {
Self {
from: self.from.clone(),
to: self.to.clone(),
auto_reverse: self.auto_reverse,
skip: self.skip,
delay: self.delay,
duration: self.duration,
repeat: self.repeat,
easing: dyn_clone::clone_box(&*self.easing),
}
}
}