use crate::utils::easing::Easing;
use std::time::Duration;
use super::Timer;
#[derive(Clone)]
pub struct SequenceStep {
pub duration: Duration,
pub easing: Easing,
pub target: f64,
}
impl SequenceStep {
pub fn new(duration: Duration, target: f64) -> Self {
Self {
duration,
easing: Easing::Linear,
target: target.clamp(0.0, 1.0),
}
}
pub fn easing(mut self, easing: Easing) -> Self {
self.easing = easing;
self
}
}
#[derive(Clone)]
pub struct Sequence {
pub steps: Vec<SequenceStep>,
current_step: usize,
timer: Timer,
value: f64,
started: bool,
pub repeat: bool,
}
impl Default for Sequence {
fn default() -> Self {
Self::new()
}
}
impl Sequence {
pub fn new() -> Self {
Self {
steps: Vec::new(),
current_step: 0,
timer: Timer::new(Duration::ZERO),
value: 0.0,
started: false,
repeat: false,
}
}
pub fn then(mut self, duration: Duration, target: f64) -> Self {
self.steps.push(SequenceStep::new(duration, target));
self
}
pub fn then_eased(mut self, duration: Duration, target: f64, easing: Easing) -> Self {
self.steps
.push(SequenceStep::new(duration, target).easing(easing));
self
}
pub fn delay(self, duration: Duration) -> Self {
let current = self.steps.last().map(|s| s.target).unwrap_or(0.0);
self.then(duration, current)
}
pub fn repeat(mut self, repeat: bool) -> Self {
self.repeat = repeat;
self
}
pub fn start(&mut self) {
self.current_step = 0;
self.value = 0.0;
self.started = true;
if let Some(step) = self.steps.first() {
self.timer = Timer::new(step.duration);
self.timer.start();
}
}
pub fn reset(&mut self) {
self.current_step = 0;
self.value = 0.0;
self.started = false;
self.timer.reset();
}
pub fn is_running(&self) -> bool {
self.started && self.current_step < self.steps.len()
}
pub fn is_complete(&self) -> bool {
self.started && self.current_step >= self.steps.len()
}
pub fn value(&mut self) -> f64 {
if !self.started || self.steps.is_empty() {
return self.value;
}
while self.current_step < self.steps.len() && self.timer.is_finished() {
self.value = self.steps[self.current_step].target;
self.current_step += 1;
if self.current_step < self.steps.len() {
self.timer = Timer::new(self.steps[self.current_step].duration);
self.timer.start();
} else if self.repeat {
self.current_step = 0;
self.timer = Timer::new(self.steps[0].duration);
self.timer.start();
}
}
if self.current_step < self.steps.len() {
let step = &self.steps[self.current_step];
let prev_value = if self.current_step == 0 {
0.0
} else {
self.steps[self.current_step - 1].target
};
let t = self.timer.progress_eased(step.easing);
self.value = prev_value + (step.target - prev_value) * t;
}
self.value
}
}