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

7
Cargo.lock generated
View file

@ -2439,6 +2439,7 @@ dependencies = [
"bytes",
"dark-light",
"glam",
"lilt",
"log",
"num-traits",
"palette",
@ -3064,6 +3065,12 @@ dependencies = [
"redox_syscall 0.5.8",
]
[[package]]
name = "lilt"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a095f60643436f4a6bddb82f7f37c1a9247990a2ee3421cf4faa43715edd5896"
[[package]]
name = "linked-hash-map"
version = "0.5.6"

View file

@ -158,6 +158,7 @@ half = "2.2"
image = { version = "0.25", default-features = false }
kamadak-exif = "0.5"
kurbo = "0.10"
lilt = "0.7"
log = "0.4"
lyon = "1.0"
lyon_path = "1.0"

View file

@ -21,6 +21,7 @@ advanced = []
bitflags.workspace = true
bytes.workspace = true
glam.workspace = true
lilt.workspace = true
log.workspace = true
num-traits.workspace = true
palette.workspace = true

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;

View file

@ -498,15 +498,16 @@ pub mod window;
pub mod advanced;
pub use crate::core::alignment;
pub use crate::core::animation;
pub use crate::core::border;
pub use crate::core::color;
pub use crate::core::gradient;
pub use crate::core::padding;
pub use crate::core::theme;
pub use crate::core::{
Alignment, Background, Border, Color, ContentFit, Degrees, Gradient,
Length, Padding, Pixels, Point, Radians, Rectangle, Rotation, Settings,
Shadow, Size, Theme, Transformation, Vector,
Alignment, Animation, Background, Border, Color, ContentFit, Degrees,
Gradient, Length, Padding, Pixels, Point, Radians, Rectangle, Rotation,
Settings, Shadow, Size, Theme, Transformation, Vector,
};
pub use crate::runtime::exit;
pub use iced_futures::Subscription;