Skip to main content

AnimationExt

Trait AnimationExt 

Source
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§

Source

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));
Source

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)));
Source

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,

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".

Implementors§

Source§

impl<E: IntoElement + 'static> AnimationExt for E