# `Plushie.Animation.Easing`
[🔗](https://github.com/plushie-ui/plushie-elixir/blob/v0.6.0/lib/plushie/animation/easing.ex#L1)

Easing function catalogue for animations and transitions.

Provides 31 named easing curves (matching the standard set from
CSS/lilt) plus custom cubic bezier support. Used by both
`Plushie.Animation.Transition` (as atoms encoded for the wire
protocol) and `Plushie.Animation` (as functions for SDK-side
interpolation).

## Named curves

Each curve has a public function that takes a progress value
`t` in `0.0..1.0` and returns the eased value. Some curves
(back, elastic, bounce) can overshoot the 0..1 range.

### Linear

Constant velocity. No acceleration or deceleration.

### Sine (ease_in, ease_out, ease_in_out)

Gentle acceleration/deceleration using sine curves. The default
`ease_in_out` is a good general-purpose choice.

### Power curves (quad, cubic, quart, quint)

Increasingly aggressive acceleration. Higher power = sharper
start/stop.

### Exponential (expo)

Very sharp acceleration. Starts almost stationary, then
accelerates rapidly.

### Circular (circ)

Based on circular arc geometry. Moderate sharpness.

### Back

Overshoots the target slightly before settling. Good for
playful, bouncy interfaces.

### Elastic

Oscillates around the target like a spring on a rubber band.
Large overshoot.

### Bounce

Simulates a bouncing ball. Multiple diminishing bounces at the
end.

## Cubic bezier

For custom curves, pass `{:cubic_bezier, x1, y1, x2, y2}`:

    opacity: transition(300, to: 0.0, easing: {:cubic_bezier, 0.25, 0.1, 0.25, 1.0})

Control points match the CSS `cubic-bezier()` function.

# `named`

```elixir
@type named() ::
  :linear
  | :ease_in
  | :ease_out
  | :ease_in_out
  | :ease_in_quad
  | :ease_out_quad
  | :ease_in_out_quad
  | :ease_in_cubic
  | :ease_out_cubic
  | :ease_in_out_cubic
  | :ease_in_quart
  | :ease_out_quart
  | :ease_in_out_quart
  | :ease_in_quint
  | :ease_out_quint
  | :ease_in_out_quint
  | :ease_in_expo
  | :ease_out_expo
  | :ease_in_out_expo
  | :ease_in_circ
  | :ease_out_circ
  | :ease_in_out_circ
  | :ease_in_back
  | :ease_out_back
  | :ease_in_out_back
  | :ease_in_elastic
  | :ease_out_elastic
  | :ease_in_out_elastic
  | :ease_in_bounce
  | :ease_out_bounce
  | :ease_in_out_bounce
```

# `t`

```elixir
@type t() :: named() | {:cubic_bezier, float(), float(), float(), float()}
```

# `cubic_bezier`

```elixir
@spec cubic_bezier(
  t :: float(),
  x1 :: float(),
  y1 :: float(),
  x2 :: float(),
  y2 :: float()
) :: float()
```

Evaluates a cubic bezier easing curve at progress `t`.

Control points `(x1, y1)` and `(x2, y2)` match the CSS
`cubic-bezier()` function. The curve starts at `(0, 0)` and
ends at `(1, 1)`.

Uses Newton-Raphson iteration to solve for the parameter given
the x coordinate, then evaluates y at that parameter.

# `ease_in`

```elixir
@spec ease_in(float()) :: float()
```

Sine ease in: gentle acceleration.

# `ease_in_back`

```elixir
@spec ease_in_back(float()) :: float()
```

Back ease in: pulls back before accelerating.

# `ease_in_bounce`

```elixir
@spec ease_in_bounce(float()) :: float()
```

Bounce ease in.

# `ease_in_circ`

```elixir
@spec ease_in_circ(float()) :: float()
```

Circular ease in.

# `ease_in_cubic`

```elixir
@spec ease_in_cubic(float()) :: float()
```

Cubic ease in.

# `ease_in_elastic`

```elixir
@spec ease_in_elastic(float()) :: float()
```

Elastic ease in: oscillates then accelerates.

# `ease_in_expo`

```elixir
@spec ease_in_expo(float()) :: float()
```

Exponential ease in.

# `ease_in_out`

```elixir
@spec ease_in_out(float()) :: float()
```

Sine ease in-out: gentle acceleration and deceleration.

# `ease_in_out_back`

```elixir
@spec ease_in_out_back(float()) :: float()
```

Back ease in-out: pulls back and overshoots.

# `ease_in_out_bounce`

```elixir
@spec ease_in_out_bounce(float()) :: float()
```

Bounce ease in-out.

# `ease_in_out_circ`

```elixir
@spec ease_in_out_circ(float()) :: float()
```

Circular ease in-out.

# `ease_in_out_cubic`

```elixir
@spec ease_in_out_cubic(float()) :: float()
```

Cubic ease in-out.

# `ease_in_out_elastic`

```elixir
@spec ease_in_out_elastic(float()) :: float()
```

Elastic ease in-out.

# `ease_in_out_expo`

```elixir
@spec ease_in_out_expo(float()) :: float()
```

Exponential ease in-out.

# `ease_in_out_quad`

```elixir
@spec ease_in_out_quad(float()) :: float()
```

Quadratic ease in-out.

# `ease_in_out_quart`

```elixir
@spec ease_in_out_quart(float()) :: float()
```

Quartic ease in-out.

# `ease_in_out_quint`

```elixir
@spec ease_in_out_quint(float()) :: float()
```

Quintic ease in-out.

# `ease_in_quad`

```elixir
@spec ease_in_quad(float()) :: float()
```

Quadratic ease in.

# `ease_in_quart`

```elixir
@spec ease_in_quart(float()) :: float()
```

Quartic ease in.

# `ease_in_quint`

```elixir
@spec ease_in_quint(float()) :: float()
```

Quintic ease in.

# `ease_out`

```elixir
@spec ease_out(float()) :: float()
```

Sine ease out: gentle deceleration.

# `ease_out_back`

```elixir
@spec ease_out_back(float()) :: float()
```

Back ease out: overshoots then settles.

# `ease_out_bounce`

```elixir
@spec ease_out_bounce(float()) :: float()
```

Bounce ease out: bouncing ball effect.

# `ease_out_circ`

```elixir
@spec ease_out_circ(float()) :: float()
```

Circular ease out.

# `ease_out_cubic`

```elixir
@spec ease_out_cubic(float()) :: float()
```

Cubic ease out.

# `ease_out_elastic`

```elixir
@spec ease_out_elastic(float()) :: float()
```

Elastic ease out: overshoots with oscillation.

# `ease_out_expo`

```elixir
@spec ease_out_expo(float()) :: float()
```

Exponential ease out.

# `ease_out_quad`

```elixir
@spec ease_out_quad(float()) :: float()
```

Quadratic ease out.

# `ease_out_quart`

```elixir
@spec ease_out_quart(float()) :: float()
```

Quartic ease out.

# `ease_out_quint`

```elixir
@spec ease_out_quint(float()) :: float()
```

Quintic ease out.

# `function`

```elixir
@spec function(t()) :: (float() -&gt; float())
```

Returns the Elixir easing function for SDK-side interpolation.

The returned function takes a float `t` in `0.0..1.0` and
returns the eased progress value.

# `interpolate`

```elixir
@spec interpolate(a :: number(), b :: number(), t :: float(), easing :: t()) ::
  float()
```

Interpolates a value from `a` to `b` at progress `t` with the
given easing.

    iex> Easing.interpolate(0.0, 100.0, 0.5, :linear)
    50.0

# `linear`

```elixir
@spec linear(float()) :: float()
```

Linear easing: constant velocity.

# `name`

```elixir
@spec name(t()) :: String.t() | map()
```

Returns the wire-format string for an easing spec.

# `named_easings`

```elixir
@spec named_easings() :: [named()]
```

Returns the list of all named easing atoms.

# `valid?`

```elixir
@spec valid?(term()) :: boolean()
```

Returns true if the value is a valid easing spec.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
