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

Renderer-side timed transition descriptor.

Declares animation intent in the view. The renderer handles
interpolation locally with zero wire traffic during animation.

## Three forms

    # 1. Keyword (duration positional shorthand)
    opacity: transition(300, to: 0.0)
    opacity: transition(300, to: 0.0, easing: :ease_out, delay: 100)

    # 2. Keyword (all keyword)
    opacity: transition(to: 0.0, duration: 300)

    # 3. Pipeline
    alias Plushie.Animation.Transition
    opacity: Transition.new(300, to: 0.0) |> Transition.easing(:ease_out)

    # 4. Do-block
    opacity: transition 300 do
      to 0.0
      easing :ease_out
      delay 100
    end

## Enter animations

Use `from:` to set the starting value on mount:

    container "item",
      opacity: transition(200, to: 1.0, from: 0.0),
      translate_y: transition(200, to: 0, from: 20, delay: 50) do
      ...
    end

On mount, the renderer uses `from:` as the starting value and
animates to `to:`. Without `from:`, the target value is used
immediately (no enter animation). On subsequent renders, `from:`
is ignored and animation starts from the current interpolated
value.

## Looping

`loop/1` and `loop/2` are convenience constructors for repeating
transitions:

    # Pulse forever
    opacity: loop(800, to: 0.4, from: 1.0)

    # Spin forever (no reverse)
    rotation: loop(1000, to: 360, from: 0, auto_reverse: false)

    # Finite: 3 cycles
    opacity: loop(800, to: 0.4, from: 1.0, cycles: 3)

## Completion events

Use `on_complete:` to receive a `%WidgetEvent{type: :transition_complete}`
when the animation finishes:

    opacity: transition(300, to: 0.0, on_complete: :faded_out)

# `t`

```elixir
@type t() :: %Plushie.Animation.Transition{
  auto_reverse: boolean(),
  delay: non_neg_integer(),
  duration: pos_integer() | nil,
  easing: Plushie.Animation.Easing.t(),
  from: term() | nil,
  on_complete: atom() | nil,
  repeat: pos_integer() | :forever | nil,
  to: term()
}
```

# `auto_reverse`

```elixir
@spec auto_reverse(transition :: t(), auto_reverse :: boolean()) :: t()
```

Sets whether the animation reverses on each repeat cycle.

# `delay`

```elixir
@spec delay(transition :: t(), delay :: non_neg_integer()) :: t()
```

Sets the delay before the transition starts (milliseconds).

# `duration`

```elixir
@spec duration(transition :: t(), duration :: pos_integer()) :: t()
```

Sets the duration in milliseconds.

# `easing`

```elixir
@spec easing(transition :: t(), easing :: Plushie.Animation.Easing.t()) :: t()
```

Sets the easing function.

# `from`

```elixir
@spec from(transition :: t(), from :: term()) :: t()
```

Sets the explicit start value (for enter animations and loop reset).

# `from_opts`

# `loop`

```elixir
@spec loop(opts :: keyword()) :: t()
```

Creates a looping transition with all keyword arguments.

Sets `repeat: :forever` and `auto_reverse: true` by default.
`to:`, `from:`, and `duration:` are required.

    Transition.loop(to: 0.4, from: 1.0, duration: 800)
    Transition.loop(to: 0.4, from: 1.0, duration: 800, easing: :ease_in_out)

# `loop`

```elixir
@spec loop(duration :: pos_integer(), opts :: keyword()) :: t()
```

Creates a looping transition with duration as a positional argument.

    Transition.loop(800, to: 0.4, from: 1.0)
    Transition.loop(800, to: 0.4, from: 1.0, cycles: 3)

# `new`

```elixir
@spec new(opts :: keyword()) :: t()
```

Creates a new transition with all keyword arguments.

`to:` and `duration:` are required.

    Transition.new(to: 0.0, duration: 300)
    Transition.new(to: 0.0, duration: 300, easing: :ease_out)

# `new`

```elixir
@spec new(duration :: pos_integer(), opts :: keyword()) :: t()
```

Creates a new transition with duration as a positional argument.

`to:` is required in the keyword opts.

    Transition.new(300, to: 0.0)
    Transition.new(300, to: 0.0, easing: :ease_out, delay: 100)

# `on_complete`

```elixir
@spec on_complete(transition :: t(), tag :: atom()) :: t()
```

Sets the completion event tag.

# `repeat`

```elixir
@spec repeat(transition :: t(), repeat :: pos_integer() | :forever) :: t()
```

Sets the repeat count (positive integer or `:forever`).

# `to`

```elixir
@spec to(transition :: t(), to :: term()) :: t()
```

Sets the target value.

# `with_options`

```elixir
@spec with_options(transition :: t(), opts :: keyword()) :: t()
```

Applies keyword options to an existing transition.

---

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