# Transições de tela

> Animar a troca de janela (fade/slide/scale) declarando WindowStyle.transition.

Source: https://crossfly.dev/pt/docs/ui/animations/screen-transitions — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Transições de tela

Ao `show()`/`hide()` de uma janela, o CrossFly pode animar a troca capturando a tela **antes** e
**depois** e interpolando entre elas. Você **declara** o efeito no `WindowStyle`; o framework dispara
a transição sozinho.

## Exemplo completo (copiar, colar e rodar)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      // Declare a transição ANTES de montar a UI (o "antes" é capturado no primeiro paint).
      // getStyle() infere WindowStyle aqui, onde transition(...) está definido.
      getStyle().transition(UIConstants.Transition.SLIDE_LEFT, 0.4f);   // efeito + duração (s)

      setLayout(new VerticalLayout());
      Label titulo = new Label("Nova tela");
      add(LAY_AUTO, titulo);

      Button avancar = new Button("Avançar");
      add(LAY_AUTO, avancar);
      // Ao empilhar outra janela com transição SLIDE_LEFT, o framework anima a troca sozinho:
      avancar.onAction(c -> new MainWindow().show());
   }
}
```
> Os trechos abaixo mostram **só o miolo** (o que vai dentro de `onShow()`). Para rodar, coloque-os no esqueleto `MainWindow` acima.

## O jeito declarativo (recomendado)
Defina o efeito no estilo da janela — em `onShow()`, antes de nada aparecer:
```java
@Override public void onShow() throws Exception {
   super.onShow();
   getStyle().transition(UIConstants.Transition.SLIDE_LEFT, 0.4f);  // efeito + duração (s)
   // … monta a UI …
}
```
Ou pelos campos/fluentes do `WindowStyle`:
```java
getStyle().transition = UIConstants.Transition.FADE;   // campo público
getStyle().transitionDuration = 0.3f;
// equivalente fluente:
getStyle().transition(UIConstants.Transition.FADE).transitionDuration(0.3f);
```

## Efeitos disponíveis (`UIConstants.Transition`)
| Valor | Efeito |
|---|---|
| `NONE` | troca instantânea (padrão) |
| `FADE` | esmaece uma tela sobre a outra |
| `SLIDE_LEFT` / `SLIDE_RIGHT` | desliza no eixo horizontal |
| `SLIDE_UP` / `SLIDE_DOWN` | desliza no eixo vertical |
| `SCALE` | nova tela cresce a partir do centro |
| `SCALE_DOWN` | tela atual encolhe para o centro |

> Padrões: `WindowStyle.transition` inicia em `NONE` e `transitionDuration` em `0.5s`. **Pickers** já
> usam `FADE` por padrão.

## Como funciona por baixo
`ScreenTransition.begin(Transition, duration)` captura a tela atual como "antes", a nova como
"depois" no próximo frame e interpola (usando um `AlphaAnimation` interno). Você **não** costuma
chamar isso — o `Window.show()`/`hide()` chama quando há `transition != NONE`.

## Boas práticas
- Escolha o efeito pela **intenção de navegação**: `SLIDE_LEFT` para avançar, `SLIDE_RIGHT`/`SCALE_DOWN`
  para voltar.
- Mantenha durações curtas (0,25–0,4s) — transições longas atrapalham.
- Defina a transição em `onShow()` (antes de a janela ser pintada).

## Erros comuns
- Definir a transição tarde demais (depois do primeiro paint) — o "antes" já mudou.
- Durações longas que deixam a navegação lenta.

## Veja também
- [Animações de valor](/docs/ui/animations/value-animations) · [A pilha de janelas](/docs/ui/navigation/the-window-stack)
