# How to fade a component in/out

> Animate a component's opacity with AlphaAnimation, applying the value via alpha() and repainting on demand.

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

# How to fade a component in/out

**Purpose.** Make a component appear smoothly (0 → 1) or disappear (1 → 0). `AlphaAnimation` interpolates a `float` with ease-in-out; you apply that value to the component's opacity and force a repaint.

## APIs used
- `new AlphaAnimation(float start, float end, float duration [, float fps])` — creates the animation. `start`/`end` are **clamped to [0,1]**; **cubic ease-in-out** interpolation; `duration` in seconds; `fps` optional (default 60).
- `AlphaAnimation.onUpdate(Runnable)` — callback on each frame; read `getValue()` here.
- `AlphaAnimation.onComplete(Runnable)` — callback when reaching `end` (also triggered by `stop()`).
- `AlphaAnimation.getValue()` — current interpolated value.
- `AlphaAnimation.start()` / `stop()` / `cancel()` — starts / stops (triggers `onComplete`) / cancels (does not trigger).
- `Component.alpha(float)` — sets the component's opacity (0–1, clamped). **Javadoc discrepancy:** the doc cites `setAlpha`, but the actual method is `alpha(...)`.
- `Component.repaint()` — **static** method; requests a re-render (CrossFly renders on demand, so calling it inside `onUpdate` is required).

## Full example (copy, paste and run)
```java
package com.exemplo;

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

/** Runnable main screen: applies a fade-in on a Label when opened. */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

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

      // Declare the variable beforehand so you can read getValue() inside onUpdate.
      AlphaAnimation anim = new AlphaAnimation(0f, 1f, 0.3f);       // 300 ms, 0 → 1
      anim.onUpdate(() ->
         {
            c.alpha(anim.getValue());   // applies opacity
            Component.repaint();        // render on demand: without this, the frame isn't redrawn
         })
         .onComplete(() -> Component.repaint())
         .start();
   }
}
```

> The snippet below shows **only the core**. To run it, place it inside the `MainWindow` skeleton above.

## Minimal snippet
```java
// verified in the source: AlphaAnimation clamp [0,1] ease-in-out; Component.alpha(float); Component.repaint() static
Label c = new Label("Olá");
add(c);

// Declare the variable beforehand so you can read getValue() inside onUpdate.
AlphaAnimation anim = new AlphaAnimation(0f, 1f, 0.3f);       // 300 ms, 0 → 1
anim.onUpdate(() ->
   {
      c.alpha(anim.getValue());   // applies opacity
      Component.repaint();        // render on demand: without this, the frame isn't redrawn
   })
   .onComplete(() -> Component.repaint())
   .start();
```

Notes:

- `alpha(1f)` (or `>= 0.999`) removes the opacity property (component 100% opaque); `alpha(0f)` makes it invisible but still present in the layout.
- For a fade-out use `new AlphaAnimation(1f, 0f, 0.3f)` and, in `onComplete`, `hide()`/remove the component if you wish.
- **Always** call `Component.repaint()` in `onUpdate` — CrossFly only redraws when requested.

## Dig deeper
- [Value animations](/docs/ui/animations/value-animations)
- Sibling recipe: [Pulse in a loop](/docs/cookbook/anim/pulso-loop) · [Move a component](/docs/cookbook/anim/mover-componente)
- Related: [Open and close a screen](/docs/cookbook/nav/abrir-tela)
