# gpui: Add spring animations; examples \(\#62778\) · gitcafe/zed

[View on GitCafe](https://git.cafe/gitcafe/zed/commit/8b1497dbd22fb06f5838a7c0b84a1e54fafa71bc)

Repository: [gitcafe/zed](https://git.cafe/gitcafe/zed)

Visibility: public

Requested revision: 8b1497dbd22fb06f5838a7c0b84a1e54fafa71bc

Requested commit: 8b1497dbd22fb06f5838a7c0b84a1e54fafa71bc

Commit: 8b1497dbd22fb06f5838a7c0b84a1e54fafa71bc

Tree: 85eccaf309692769ec7458482ec7b39c6faf430f

Author: David Barsky

Committer: GitHub

## Message

````
gpui: Add spring animations; examples (#62778)

# Objective

I wanted spring animations in GPUI for an application built atop of
GPUI.

## Solution

I texted @mikayla-maki about wanting spring animations; we collaborated
in Delta; this change is the co-authored result. We built atop of GPUI's
existing APIs, but this *is* new API surface. The verbiage is borrowed
from SwiftUI's approach.

First, what _are_ spring animations? If you're unfamiliar, they're the
bouncy, physical animations that you'd often see in mobile applications.
As Claude put it to me, "keyframe animation is a recording; a spring is
a simulation". There's a few consequences:
1. The animation API needs to support interrupts/cancelation, or the
application using spring animations will feel broken. You need to cancel
the momentum in a physically realistic way!
2. The API is more complex! GPUI's existing animations are, roughly,
`Fn(progress: f32) -> eased_progress: f32`, but a spring animation is
closer to `Fn(state: SpringState, target: f32, delta_time: f32) ->
SpringState`. Concretely, GPUI landed on the following:

```
pub fn step(
    &self,
    state: SpringState,
    target: f32,
    delta_time: f32,
) -> SpringState;
```

...where `&self` is:
```
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SpringConfig {
    /// The spring stiffness, conventionally written as $k$.
    pub stiffness: f32,
    /// The viscous damping coefficient, conventionally written as $c$.
    pub damping: f32,
    /// The moving mass, conventionally written as $m$.
    pub mass: f32,
}
```

Conceptually, at each frame, GPUI does `let state = spring.step(state,
target, delta_time);`, or as an other LLM summarized:

```
// Ordinary animation:
progress: f32 -> phase: f32

// GPUI spring:
(state: { position, velocity }, target, dt)
    -> new { position, velocity }
    -> typed presentation value
```

---

Release Notes:

- gpui: Added spring animations
````

## Parents

- [eb5483528be607b497afdaad0a237bebeb191249](https://git.cafe/gitcafe/zed/commit/eb5483528be607b497afdaad0a237bebeb191249?format=markdown)

[Source at this commit](https://git.cafe/gitcafe/zed/tree/8b1497dbd22fb06f5838a7c0b84a1e54fafa71bc?format=markdown)
