Animaciones en JavaFX: De Timeline a Transiciones
Aprende a crear animaciones fluidas en JavaFX con demos interactivas en vivo. Desde FadeTransition hasta animaciones combinadas con Timeline, cada ejemplo incluye una demo visual y el código Java completo.
JavaFX Master
4 de marzo de 2025 • 14 min de lectura
Las animaciones son lo que hace que una interfaz pase de ser funcional a sentirse viva. JavaFX incluye un sistema de animaciones potente con transiciones predefinidas y la flexibilidad de Timeline para crear cualquier animación personalizada.
En este artículo cada ejemplo tiene una demo interactiva para que veas la animación en acción, seguida del código JavaFX equivalente.
1. Fade (Opacidad)
La animación más básica y útil. Perfecta para mostrar/ocultar elementos con elegancia.
Código JavaFX
import javafx.animation.FadeTransition;
import javafx.util.Duration;
FadeTransition fade = new FadeTransition(Duration.millis(700), nodo);
fade.setFromValue(1.0);
fade.setToValue(0.0);
fade.play();
// Para hacer Fade In, invierte los valores:
fade.setFromValue(0.0);
fade.setToValue(1.0);
Tip: Usa
fade.setAutoReverse(true)yfade.setCycleCount(Animation.INDEFINITE)para crear un efecto de "respiración" continuo.
2. Scale (Escala)
Agranda o reduce un elemento. Ideal para botones al hacer hover o para resaltar elementos seleccionados.
Código JavaFX
import javafx.animation.ScaleTransition;
import javafx.util.Duration;
ScaleTransition scale = new ScaleTransition(Duration.millis(500), nodo);
scale.setFromX(1.0);
scale.setFromY(1.0);
scale.setToX(1.5);
scale.setToY(1.5);
scale.play();
Para un efecto de botón hover, usa un listener:
boton.setOnMouseEntered(e -> {
ScaleTransition st = new ScaleTransition(Duration.millis(200), boton);
st.setToX(1.1);
st.setToY(1.1);
st.play();
});
boton.setOnMouseExited(e -> {
ScaleTransition st = new ScaleTransition(Duration.millis(200), boton);
st.setToX(1.0);
st.setToY(1.0);
st.play();
});
3. Slide (Desplazamiento)
Mueve un elemento de un punto a otro. Útil para paneles deslizantes, sidebars y notificaciones.
Código JavaFX
import javafx.animation.TranslateTransition;
import javafx.util.Duration;
TranslateTransition slide = new TranslateTransition(Duration.millis(500), nodo);
slide.setFromX(0);
slide.setToX(200); // Mover 200px a la derecha
slide.play();
// Para una sidebar que se desliza desde la izquierda:
TranslateTransition showSidebar = new TranslateTransition(Duration.millis(300), sidebar);
showSidebar.setFromX(-250); // Empieza fuera de pantalla
showSidebar.setToX(0); // Termina en posición
showSidebar.play();
4. Rotate (Rotación)
Rota un elemento sobre su centro. Perfecto para iconos de carga, flechas expandibles y efectos decorativos.
Código JavaFX
import javafx.animation.RotateTransition;
import javafx.util.Duration;
RotateTransition rotate = new RotateTransition(Duration.millis(700), nodo);
rotate.setFromAngle(0);
rotate.setToAngle(180);
rotate.play();
// Spinner infinito:
RotateTransition spinner = new RotateTransition(Duration.millis(1000), iconoCarga);
spinner.setFromAngle(0);
spinner.setToAngle(360);
spinner.setCycleCount(Animation.INDEFINITE);
spinner.setInterpolator(Interpolator.LINEAR);
spinner.play();
5. Color (Cambio de Color)
Cambia el color de fondo de un componente gradualmente. Útil para estados de validación, temas y feedback visual.
Código JavaFX
JavaFX no tiene un ColorTransition directo, pero lo puedes crear con Timeline:
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.paint.Color;
import javafx.util.Duration;
ObjectProperty<Color> colorProp = new SimpleObjectProperty<>(Color.web("#0ea5e9"));
colorProp.addListener((obs, oldColor, newColor) -> {
nodo.setStyle(String.format(
"-fx-background-color: rgb(%d,%d,%d);",
(int)(newColor.getRed() * 255),
(int)(newColor.getGreen() * 255),
(int)(newColor.getBlue() * 255)
));
});
Timeline colorAnim = new Timeline(
new KeyFrame(Duration.ZERO,
new KeyValue(colorProp, Color.web("#0ea5e9"))),
new KeyFrame(Duration.millis(700),
new KeyValue(colorProp, Color.web("#f43f5e")))
);
colorAnim.play();
6. Animaciones Combinadas
La magia real ocurre cuando combinas múltiples animaciones. Puedes usar ParallelTransition para ejecutar varias a la vez.
Código JavaFX
import javafx.animation.ParallelTransition;
import javafx.animation.FadeTransition;
import javafx.animation.ScaleTransition;
import javafx.animation.RotateTransition;
import javafx.animation.TranslateTransition;
import javafx.util.Duration;
// Crear transiciones individuales
FadeTransition fade = new FadeTransition(Duration.millis(700), nodo);
fade.setToValue(0.8);
ScaleTransition scale = new ScaleTransition(Duration.millis(700), nodo);
scale.setToX(1.25);
scale.setToY(1.25);
RotateTransition rotate = new RotateTransition(Duration.millis(700), nodo);
rotate.setToAngle(12);
TranslateTransition move = new TranslateTransition(Duration.millis(700), nodo);
move.setToX(32);
// Ejecutar todas en paralelo
ParallelTransition combo = new ParallelTransition(fade, scale, rotate, move);
combo.play();
También puedes encadenar animaciones con SequentialTransition:
import javafx.animation.SequentialTransition;
SequentialTransition secuencia = new SequentialTransition(
fade, // Primero fade
scale, // Luego escala
rotate // Finalmente rotación
);
secuencia.play();
7. Efectos Hover
Los efectos hover hacen que la interfaz se sienta interactiva y responsiva. Pasa el mouse sobre estos elementos:
Pasa el mouse sobre los cuadros
Código JavaFX
// Efecto Scale on Hover
nodo.setOnMouseEntered(e -> {
ScaleTransition st = new ScaleTransition(Duration.millis(200), nodo);
st.setToX(1.1);
st.setToY(1.1);
st.play();
});
nodo.setOnMouseExited(e -> {
ScaleTransition st = new ScaleTransition(Duration.millis(200), nodo);
st.setToX(1.0);
st.setToY(1.0);
st.play();
});
// Efecto Lift (mover hacia arriba)
nodo.setOnMouseEntered(e -> {
TranslateTransition tt = new TranslateTransition(Duration.millis(200), nodo);
tt.setToY(-8);
tt.play();
});
nodo.setOnMouseExited(e -> {
TranslateTransition tt = new TranslateTransition(Duration.millis(200), nodo);
tt.setToY(0);
tt.play();
});
// Efecto con DropShadow
import javafx.scene.effect.DropShadow;
import javafx.scene.paint.Color;
DropShadow shadow = new DropShadow(10, Color.rgb(59, 130, 246, 0.5));
nodo.setOnMouseEntered(e -> nodo.setEffect(shadow));
nodo.setOnMouseExited(e -> nodo.setEffect(null));
8. Animaciones Infinitas
Animaciones que se repiten continuamente, útiles para indicadores de carga, notificaciones y elementos decorativos.
Animaciones infinitas: pulse, bounce, spin, ping
Código JavaFX
// Pulse (opacidad pulsante)
FadeTransition pulse = new FadeTransition(Duration.millis(1000), nodo);
pulse.setFromValue(1.0);
pulse.setToValue(0.5);
pulse.setAutoReverse(true);
pulse.setCycleCount(Animation.INDEFINITE);
pulse.play();
// Bounce (rebote vertical)
TranslateTransition bounce = new TranslateTransition(Duration.millis(500), nodo);
bounce.setFromY(0);
bounce.setToY(-20);
bounce.setAutoReverse(true);
bounce.setCycleCount(Animation.INDEFINITE);
bounce.setInterpolator(Interpolator.EASE_BOTH);
bounce.play();
// Spin (rotación continua)
RotateTransition spin = new RotateTransition(Duration.millis(1000), nodo);
spin.setFromAngle(0);
spin.setToAngle(360);
spin.setCycleCount(Animation.INDEFINITE);
spin.setInterpolator(Interpolator.LINEAR);
spin.play();
Interpoladores
Los interpoladores controlan la curva de velocidad de la animación. JavaFX incluye varios:
| Interpolador | Efecto |
|---|---|
Interpolator.LINEAR | Velocidad constante |
Interpolator.EASE_IN | Empieza lento, termina rápido |
Interpolator.EASE_OUT | Empieza rápido, termina suave |
Interpolator.EASE_BOTH | Suave al inicio y final |
Interpolator.SPLINE(a,b,c,d) | Curva Bézier personalizada |
// Animación con ease-out para un movimiento natural
TranslateTransition slide = new TranslateTransition(Duration.millis(400), nodo);
slide.setToX(200);
slide.setInterpolator(Interpolator.EASE_OUT);
slide.play();
Clase Helper: AnimationUtils
Para no repetir código, crea una clase utilitaria:
public class AnimationUtils {
public static void fadeIn(Node nodo, double duracionMs) {
FadeTransition ft = new FadeTransition(Duration.millis(duracionMs), nodo);
ft.setFromValue(0);
ft.setToValue(1);
ft.play();
}
public static void fadeOut(Node nodo, double duracionMs, Runnable onFinish) {
FadeTransition ft = new FadeTransition(Duration.millis(duracionMs), nodo);
ft.setFromValue(1);
ft.setToValue(0);
if (onFinish != null) ft.setOnFinished(e -> onFinish.run());
ft.play();
}
public static void scaleHover(Node nodo, double factor) {
nodo.setOnMouseEntered(e -> {
ScaleTransition st = new ScaleTransition(Duration.millis(150), nodo);
st.setToX(factor);
st.setToY(factor);
st.play();
});
nodo.setOnMouseExited(e -> {
ScaleTransition st = new ScaleTransition(Duration.millis(150), nodo);
st.setToX(1.0);
st.setToY(1.0);
st.play();
});
}
public static void slideIn(Node nodo, double fromX, double duracionMs) {
nodo.setTranslateX(fromX);
TranslateTransition tt = new TranslateTransition(Duration.millis(duracionMs), nodo);
tt.setToX(0);
tt.setInterpolator(Interpolator.EASE_OUT);
tt.play();
}
}
Uso:
AnimationUtils.fadeIn(miPanel, 300);
AnimationUtils.scaleHover(miBoton, 1.1);
AnimationUtils.slideIn(sidebar, -250, 400);
Siguiente Paso
Con estas animaciones ya tienes las herramientas para crear interfaces que se sientan profesionales y vivas. En el próximo artículo exploraremos cómo crear componentes reutilizables como tarjetas, barras de estado y notificaciones toast.