pub trait AnimationExt {
// Provided methods
fn with_animation(
self,
id: impl Into<ElementId>,
animation: Animation,
animator: impl Fn(Self, f32) -> Self + 'static,
) -> AnimationElement<Self>
where Self: Sized { ... }
fn with_animations(
self,
id: impl Into<ElementId>,
animations: Vec<Animation>,
animator: impl Fn(Self, usize, f32) -> Self + 'static,
) -> AnimationElement<Self>
where Self: Sized { ... }
fn with_spring<T>(
self,
id: impl Into<ElementId>,
animation: SpringAnimation<T>,
animator: impl FnOnce(Self, T::Output) -> Self + 'static,
) -> SpringAnimationElement<Self>
where Self: Sized,
T: SpringTarget,
T::Output: 'static { ... }
}Expand description
Adds animation methods to every element and component.
It is implemented for any IntoElement type, so you can call these methods on a
Div or on your own component.
Animations honor App::reduce_motion. When it is set, the element
renders in a static state: the end state for a one-pass animation, and the start state for a
repeating one. No animation frames are scheduled. GPUI doesn’t read the operating system’s
setting, so set it yourself with App::set_reduce_motion.
Provided Methods§
Sourcefn with_animation(
self,
id: impl Into<ElementId>,
animation: Animation,
animator: impl Fn(Self, f32) -> Self + 'static,
) -> AnimationElement<Self>where
Self: Sized,
fn with_animation(
self,
id: impl Into<ElementId>,
animation: Animation,
animator: impl Fn(Self, f32) -> Self + 'static,
) -> AnimationElement<Self>where
Self: Sized,
Renders this element with animation, passing animator the eased progress on every frame.
animator receives the element and a value from 0.0 to 1.0, and returns the styled
element. The id identifies the animation across frames. Change it to start the animation
again, and keep it stable otherwise, or the animation restarts on every render.
§Examples
Under reduce motion, a one-pass animation renders at its end state, 1.0.
use std::{cell::RefCell, rc::Rc, time::Duration};
use gpui::{
Animation, AnimationExt, Context, IntoElement, Render, TestApp, Window, div, prelude::*, px,
};
struct Toast {
deltas: Rc<RefCell<Vec<f32>>>,
}
impl Render for Toast {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
let deltas = self.deltas.clone();
div().child("Saved").with_animation(
"toast-enter",
Animation::new(Duration::from_millis(300)),
move |toast, delta| {
deltas.borrow_mut().push(delta);
toast.opacity(delta).mt(px(8. * (1. - delta)))
},
)
}
}
let deltas = Rc::new(RefCell::new(Vec::new()));
let mut app = TestApp::new();
app.update(|cx| cx.set_reduce_motion(true));
let mut window = app.open_window(|_, _| Toast { deltas: deltas.clone() });
window.draw();
assert_eq!(deltas.borrow().last(), Some(&1.0));Sourcefn with_animations(
self,
id: impl Into<ElementId>,
animations: Vec<Animation>,
animator: impl Fn(Self, usize, f32) -> Self + 'static,
) -> AnimationElement<Self>where
Self: Sized,
fn with_animations(
self,
id: impl Into<ElementId>,
animations: Vec<Animation>,
animator: impl Fn(Self, usize, f32) -> Self + 'static,
) -> AnimationElement<Self>where
Self: Sized,
Renders this element with a sequence of animations, one after another.
animator receives the index of the running step and its progress from 0.0 to 1.0.
Each step starts when the one before it finishes. A repeating step never finishes, so only
the last step should repeat.
Under reduce motion, the element renders at the end of the last step.
§Panics
Panics if animations is empty. Debug builds assert this when the element is created.
§Examples
use std::{cell::RefCell, rc::Rc, time::Duration};
use gpui::{
Animation, AnimationExt, Context, IntoElement, Render, TestApp, Window, div, ease_out_quint,
prelude::*, px,
};
struct Pop {
steps: Rc<RefCell<Vec<(usize, f32)>>>,
}
impl Render for Pop {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
let steps = self.steps.clone();
div().child("Done").with_animations(
"pop",
vec![
Animation::new(Duration::from_millis(150)),
Animation::new(Duration::from_millis(300)).with_easing(ease_out_quint()),
],
move |el, step, delta| {
steps.borrow_mut().push((step, delta));
match step {
0 => el.opacity(delta),
_ => el.opacity(1.0).mt(px(8. * (1. - delta))),
}
},
)
}
}
let steps = Rc::new(RefCell::new(Vec::new()));
let mut app = TestApp::new();
app.update(|cx| cx.set_reduce_motion(true));
let mut window = app.open_window(|_, _| Pop { steps: steps.clone() });
window.draw();
assert_eq!(steps.borrow().last(), Some(&(1, 1.0)));Sourcefn with_spring<T>(
self,
id: impl Into<ElementId>,
animation: SpringAnimation<T>,
animator: impl FnOnce(Self, T::Output) -> Self + 'static,
) -> SpringAnimationElement<Self>
fn with_spring<T>( self, id: impl Into<ElementId>, animation: SpringAnimation<T>, animator: impl FnOnce(Self, T::Output) -> Self + 'static, ) -> SpringAnimationElement<Self>
Renders this element at the value of a spring, passed to animator.
The id keeps the spring’s position and velocity across frames, so a retargeted spring
bends toward the new target. A newly mounted spring starts at its target, unless you set
a start with SpringAnimation::from. Under reduce motion, the spring jumps to its target.
See SpringAnimation for an example.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".