use crate::{
keyframes::Keyframes, property::PropertySnapshot, timeline::Timeline, timing::Duration,
};
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum AnimationSource {
Keyframes(Keyframes),
Timeline(Timeline),
}
impl From<Keyframes> for AnimationSource {
fn from(value: Keyframes) -> Self {
Self::Keyframes(value)
}
}
impl From<Timeline> for AnimationSource {
fn from(value: Timeline) -> Self {
Self::Timeline(value)
}
}
impl AnimationSource {
#[must_use]
pub(crate) fn total_duration(&self) -> Option<Duration> {
match self {
Self::Keyframes(keyframes) => keyframes.timing().total_duration(),
Self::Timeline(timeline) => timeline.total_duration(),
}
}
#[must_use]
pub(crate) fn sample_at(&self, elapsed: impl Into<Duration>) -> Option<PropertySnapshot> {
match self {
Self::Keyframes(keyframes) => sample_keyframes(keyframes, elapsed.into()),
Self::Timeline(timeline) => timeline.sample_at(elapsed),
}
}
#[must_use]
pub(crate) fn completion_snapshot(&self) -> Option<PropertySnapshot> {
match self {
Self::Keyframes(keyframes) => keyframes.sample_completion(),
Self::Timeline(timeline) => timeline.completion_snapshot(),
}
}
}
fn sample_keyframes(keyframes: &Keyframes, elapsed: Duration) -> Option<PropertySnapshot> {
let timing = keyframes.timing().normalize_elapsed(elapsed.as_millis());
if !timing.has_sample() {
return None;
}
#[allow(
clippy::cast_possible_truncation,
reason = "Normalized keyframe offsets are stored as f32 throughout the keyframe module."
)]
keyframes.sample_at(timing.iteration_progress as f32)
}