Springs
A Spring is an immutable set of physics parameters. The solver evaluates it closed-form and the baker turns it into a CSS linear() easing plus a real duration.
// Pick a spring, bake it, apply the easing to a plain CSS transition.
var baked = LinearEasingBaker.Bake(Spring.Bouncy);
// baked.Easing -> "linear(0, 0.0109, 0.041, ... , 1)"
// baked.DurationMilliseconds -> 740
var style = $"transition: transform {baked.DurationMilliseconds}ms {baked.Easing};";Defining a spring
Create a spring from raw physics or from perceptual parameters. The perceptual factories solve for the physics with Newton-Raphson, so you can think in duration and bounce and let the solver find stiffness and damping.
| Factory | Returns | Notes |
|---|---|---|
| Spring.Physics(stiffness, damping, mass = 1, initialVelocity = 0) | Spring | Raw physics parameters. |
| Spring.FromDuration(durationSeconds, bounce = 0.25, initialVelocity = 0) | Spring | Perceptual: settle duration and bounce in [0, 1]. Duration is treated as the settle time. |
| Spring.FromVisualDuration(visualDurationSeconds, bounce = 0.25, initialVelocity = 0) | Spring | Perceptual: the perceived duration; the real settle duration is longer. |
| spring.WithInitialVelocity(initialVelocity) | Spring | Copy with a different starting velocity (value units per second). |
Resolved parameters
Every spring exposes its resolved physics plus the derived quantities the solver and baker use.
| Prop | Type | Default |
|---|---|---|
| Stiffness | double | - |
| Damping | double | - |
| Mass | double | 1 |
| InitialVelocity | double | 0 |
| DampingRatio | double | computed |
| AngularFrequency | double | computed |
| VisualDurationSeconds | double | computed |
| IsDurationResolved | bool | - |
| ResolvedDurationSeconds | double | 0 |
Presets
Four named springs cover most needs. Every preset is defined with FromVisualDuration, so the number is the perceived duration and the bounce sets the overshoot.
| Preset | Parameters | Feel |
|---|---|---|
| Spring.Default | visual 0.3s, bounce 0.2 | Balanced, general purpose. |
| Spring.Smooth | visual 0.35s, bounce 0 | Critically damped glide, no overshoot. |
| Spring.Snappy | visual 0.2s, bounce 0.1 | Fast and eager, a hint of life. |
| Spring.Bouncy | visual 0.35s, bounce 0.45 | Playful, clearly visible overshoot. |
Baking to CSS
LinearEasingBaker.Bake runs a spring on a normalized 0 to 1 probe through SpringSolver, samples it at a fixed 10ms resolution (constant points per second), rounds to four decimals, and returns a BakedEasing. The normalized easing is value independent, so one bake serves any keyframe pair.
var baked = LinearEasingBaker.Bake(Spring.Snappy);
Console.WriteLine(baked.Easing); // linear(0, 0.0314, ... , 1)
Console.WriteLine(baked.DurationMilliseconds); // 270
double[] keyframes = baked.MapTo(from: 0, to: 200); // the linear() fallback valuesLinearEasingBaker
Static baker. Bake a Spring (0 to 1 probe run) or an explicit SpringSolver run.
| Prop | Type | Default |
|---|---|---|
| Bake(Spring spring, double resolutionSeconds = 0.01) | BakedEasing | - |
| Bake(SpringSolver solver, double resolutionSeconds = 0.01) | BakedEasing | - |
| DefaultResolutionSeconds | const double | 0.01 |
BakedEasing
The result of a bake: the linear() easing string, the real duration it must play over, the raw sampled points (the pre-generated-keyframes fallback), and the perceptual duration multiplier (real / perceived).
| Prop | Type | Default |
|---|---|---|
| Easing | string | - |
| DurationSeconds | double | - |
| Points | IReadOnlyList<double> | - |
| PerceptualDurationMultiplier | double | - |
| DurationMilliseconds | int | computed |
| MapTo(double from, double to) | double[] | - |