# How to move a component by animating its position

> Slide a component from one point to another with PositionAnimation (linear interpolation in pixels).

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

# How to move a component by animating its position

**Purpose.** Animate a component's **position in pixels** (e.g., slide a card from the right to the center). `PositionAnimation` interpolates linearly and is **not** clamped to [0,1] — ideal for coordinates.

## APIs used
- `new PositionAnimation(float start, float end, float duration [, float fps])` — interpolates `start → end` **linearly**, **without clamp**; `duration` in seconds; `fps` optional (default 60).
- `PositionAnimation.onUpdate(Runnable)` / `onComplete(Runnable)` / `getValue()` / `start()` / `stop()` / `cancel()` — same family as `AlphaAnimation`.
- `Component.setX(int)` / `Component.setY(int)` — reposition the component (return `Component`). Alternative: `setBounds(int x, int y, int w, int h)` when also changing size.
- `Component.getY()` / `getWidth()` / `getHeight()` — to preserve the axes that are not animating.
- `Component.repaint()` — static; required in `onUpdate` (render on demand).

## 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: slides a card from the right to the center when opened. */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Card card = new Card();
      add(card);

      int fromX = Screen.width;          // starts off-screen, to the right
      int toX   = (Screen.width - card.width) / 2;   // centers horizontally

      PositionAnimation slide = new PositionAnimation(fromX, toX, 0.4f);   // 400 ms
      slide.onUpdate(() ->
         {
            card.x = (int) slide.getValue();     // moves only the X axis; Y stays (x is a public field)
            Component.repaint();                 // 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: PositionAnimation linear without clamp; Component.setX(int)/setY(int); repaint() static
Card card = new Card();
add(card);

int fromX = Screen.width;          // starts off-screen, to the right
int toX   = (Screen.width - card.getWidth()) / 2;   // centers horizontally

PositionAnimation slide = new PositionAnimation(fromX, toX, 0.4f);   // 400 ms
slide.onUpdate(() ->
   {
      card.setX((int) slide.getValue());   // moves only the X axis; Y stays
      Component.repaint();                 // without this the frame isn't redrawn
   })
   .onComplete(() -> Component.repaint())
   .start();
```

Details:

- If you need to move in X **and** Y at the same time, use **two** `PositionAnimation` (one per axis) or apply `setBounds(x, y, w, h)` in `onUpdate` computing both.
- `setX`/`setY` change the **absolute** position within the parent; on screens with automatic layout, prefer animating components whose bounds you control directly (avoid fighting the `Layout`).
- Unlike `AlphaAnimation`, there is **no** easing here: the movement is constant. For smooth movement, chain an easing into your own function or combine it with `AlphaAnimation` for the opacity effect.

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