# Cómo hacer fade (aparecer/desaparecer) de un componente

> Animar la opacidad de un componente con AlphaAnimation, aplicando el valor vía alpha() y repintando bajo demanda.

Source: https://crossfly.dev/es/docs/cookbook/anim/fade — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Cómo hacer fade (aparecer/desaparecer) de un componente

**Propósito.** Hacer que un componente aparezca suavemente (0 → 1) o desaparezca (1 → 0). `AlphaAnimation` interpola un `float` con ease-in-out; tú aplicas ese valor a la opacidad del componente y fuerzas el repaint.

## APIs usadas
- `new AlphaAnimation(float start, float end, float duration [, float fps])` — crea la animación. `start`/`end` son **limitados a [0,1]**; interpolación **ease-in-out cubic**; `duration` en segundos; `fps` opcional (por defecto 60).
- `AlphaAnimation.onUpdate(Runnable)` — callback en cada frame; lee `getValue()` aquí.
- `AlphaAnimation.onComplete(Runnable)` — callback al llegar a `end` (también disparado por `stop()`).
- `AlphaAnimation.getValue()` — valor actual interpolado.
- `AlphaAnimation.start()` / `stop()` / `cancel()` — inicia / detiene (dispara `onComplete`) / cancela (no dispara).
- `Component.alpha(float)` — define la opacidad del componente (0–1, limitada). **Divergencia de Javadoc:** el doc cita `setAlpha`, pero el método real es `alpha(...)`.
- `Component.repaint()` — método **estático**; solicita re-render (CrossFly renderiza bajo demanda, por lo que es obligatorio llamarlo dentro del `onUpdate`).

## Ejemplo completo (copiar, pegar y ejecutar)
```java
package com.exemplo;

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

/** Pantalla principal ejecutable: aplica fade-in en un Label al abrir. */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Label c = new Label("Olá");
      add(c);

      // Declara la variable antes para poder leer getValue() dentro del onUpdate.
      AlphaAnimation anim = new AlphaAnimation(0f, 1f, 0.3f);       // 300 ms, 0 → 1
      anim.onUpdate(() ->
         {
            c.alpha(anim.getValue());   // aplica opacidad
            Component.repaint();        // render bajo demanda: sin esto, el frame no se redibuja
         })
         .onComplete(() -> Component.repaint())
         .start();
   }
}
```

> El fragmento de abajo muestra **solo el núcleo**. Para ejecutarlo, colócalo en el esqueleto `MainWindow` de arriba.

## Fragmento mínimo
```java
// verificado en la fuente: AlphaAnimation clamp [0,1] ease-in-out; Component.alpha(float); Component.repaint() estático
Label c = new Label("Olá");
add(c);

// Declara la variable antes para poder leer getValue() dentro del onUpdate.
AlphaAnimation anim = new AlphaAnimation(0f, 1f, 0.3f);       // 300 ms, 0 → 1
anim.onUpdate(() ->
   {
      c.alpha(anim.getValue());   // aplica opacidad
      Component.repaint();        // render bajo demanda: sin esto, el frame no se redibuja
   })
   .onComplete(() -> Component.repaint())
   .start();
```

Notas:

- `alpha(1f)` (o `>= 0.999`) elimina la propiedad de opacidad (componente 100% opaco); `alpha(0f)` lo hace invisible pero sigue presente en el layout.
- Para fade-out usa `new AlphaAnimation(1f, 0f, 0.3f)` y, en el `onComplete`, `hide()`/elimina el componente si quieres.
- **Siempre** llama a `Component.repaint()` en el `onUpdate` — CrossFly solo redibuja cuando se le solicita.

## Profundiza
- [Animaciones de valor](/docs/ui/animations/value-animations)
- Receta hermana: [Pulso en loop](/docs/cookbook/anim/pulso-loop) · [Mover un componente](/docs/cookbook/anim/mover-componente)
- Relacionado: [Abrir y cerrar una pantalla](/docs/cookbook/nav/abrir-tela)
