Draft basic Animation API in iced_core

This commit is contained in:
Héctor Ramón Jiménez 2025-01-27 02:50:51 +01:00
parent da1726b134
commit bf600a0811
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
6 changed files with 124 additions and 3 deletions

109
core/src/animation.rs Normal file
View file

@ -0,0 +1,109 @@
//! Animate your applications.
use crate::time::{Duration, Instant};
pub use lilt::{Easing, FloatRepresentable as Float, Interpolable};
/// The animation of some particular state.
///
/// It tracks state changes and allows projecting interpolated values
/// through time.
#[derive(Debug, Clone)]
pub struct Animation<T>
where
T: Clone + Copy + PartialEq + Float,
{
raw: lilt::Animated<T, Instant>,
}
impl<T> Animation<T>
where
T: Clone + Copy + PartialEq + Float,
{
/// Creates a new [`Animation`] with the given initial state.
pub fn new(state: T) -> Self {
Self {
raw: lilt::Animated::new(state),
}
}
/// Sets the [`Easing`] function of the [`Animation`].
///
/// See the [Easing Functions Cheat Sheet](https://easings.net) for
/// details!
pub fn easing(mut self, easing: Easing) -> Self {
self.raw = self.raw.easing(easing);
self
}
/// Sets the duration of the [`Animation`] to 100ms.
pub fn very_quick(self) -> Self {
self.duration(Duration::from_millis(100))
}
/// Sets the duration of the [`Animation`] to 200ms.
pub fn quick(self) -> Self {
self.duration(Duration::from_millis(200))
}
/// Sets the duration of the [`Animation`] to 400ms.
pub fn slow(self) -> Self {
self.duration(Duration::from_millis(400))
}
/// Sets the duration of the [`Animation`] to 500ms.
pub fn very_slow(self) -> Self {
self.duration(Duration::from_millis(500))
}
/// Sets the duration of the [`Animation`] to the given value.
pub fn duration(mut self, duration: Duration) -> Self {
self.raw = self.raw.duration(duration.as_secs_f32() * 1_000.0);
self
}
/// Sets a delay for the [`Animation`].
pub fn delay(mut self, duration: Duration) -> Self {
self.raw = self.raw.delay(duration.as_secs_f64() as f32 * 1000.0);
self
}
/// Transitions the [`Animation`] from its current state to the given new state.
pub fn go(mut self, new_state: T) -> Self {
self.go_mut(new_state);
self
}
/// Transitions the [`Animation`] from its current state to the given new state, by reference.
pub fn go_mut(&mut self, new_state: T) {
self.raw.transition(new_state, Instant::now());
}
/// Returns true if the [`Animation`] is currently in progress.
///
/// An [`Animation`] is in progress when it is transitioning to a different state.
pub fn in_progress(&self, at: Instant) -> bool {
self.raw.in_progress(at)
}
/// Projects the [`Animation`] into an interpolated value at the given [`Instant`]; using the
/// closure provided to calculate the different keyframes of interpolated values.
///
/// If the [`Animation`] state is a `bool`, you can use the simpler [`interpolate`] method.
pub fn interpolate_with<I>(&self, f: impl Fn(T) -> I, at: Instant) -> I
where
I: Interpolable,
{
self.raw.animate(f, at)
}
}
impl Animation<bool> {
/// Projects the [`Animation`] into an interpolated value at the given [`Instant`]; using the
/// `start` and `end` values as the origin and destination keyframes.
pub fn interpolate<I>(&self, start: I, end: I, at: Instant) -> I
where
I: Interpolable + Clone,
{
self.raw.animate_bool(start, end, at)
}
}

View file

@ -10,6 +10,7 @@
html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"
)]
pub mod alignment;
pub mod animation;
pub mod border;
pub mod clipboard;
pub mod event;
@ -49,6 +50,7 @@ mod vector;
pub use alignment::Alignment;
pub use angle::{Degrees, Radians};
pub use animation::Animation;
pub use background::Background;
pub use border::Border;
pub use clipboard::Clipboard;