# Animation, transitions and overlays

> Keyframe animation in Envy with seven easing curves, screen transitions (fade, slide, scale) and overlay screens, identical in Godot and the browser.

Source: https://envyui.com/docs/animation

## The timeline

Open the timeline with **Alt T**. An animation belongs to a screen and has tracks of keyframes for a layer's `x`, `y`, `scale`, `rotation` and `opacity`. Values add to the layout: x and y move the layer, scale and opacity multiply, rotation adds.

Turn on **record**, move a layer, and the timeline writes the keyframe for you.

- **Autoplay** plays it when the screen opens (The Last Hunt's menu Intro).
- **Loop** repeats it (the breathing "Press any button").
- Or start it from a button's **Play** action, or from game code: `ui.play("Hit")`.

## Easing

Each key's ease shapes the segment after it: `linear`, `in`, `out`, `inOut`, `back`, `elastic`, `step`. The curves are the same functions in TypeScript and GDScript, so motion matches on both sides.

## Screen transitions

A screen can say how it appears when you go to it:

```json
"transition": { "type": "fade", "duration": 0.3 }
```

| Type | Effect |
|---|---|
| `fade` | The old screen fades out while the new one fades in |
| `slide` | Both move in a direction; the new screen enters from the opposite edge |
| `scale` | The new screen grows from 92% to 100% while fading in |

A `goto` or `push` action can override it, and so can code: `ui.goto("12 Pause", { transition: { type: "none" } })`. The old screen stays mounted but takes no input until the new one has arrived. On the web, transitions are skipped for people who ask their system for reduced motion.

## Overlays

`push` opens a screen over the current one: a pause menu over the HUD. Screens below keep their state, follow data and keep animating, but take no input until they're on top again. Focus moves into the overlay and comes back to the button that opened it. `pop` closes the top screen. The overlay's own background is what dims the screen below, so give it a semi-transparent fill.

```gdscript
ui.push("12 Pause")
ui.pop()
```
