View Transitions
Las transiciones de vista proporcionan transiciones animadas cuando el DOM cambia, reduciendo la ruptura visual y manteniendo el contexto espacial durante la navegación o actualizaciones de contenido. webforJ se integra con la API de Transición de Vista del navegador para manejar la complejidad de coordinar animaciones entre antiguos y nuevos estados.
Mostrar Código
- ViewTransitionChatView.java
- chat.css
- DemoHeader.java
- demo-header.css
Uso básico
Para crear una transición de vista, usa Page.getCurrent().startViewTransition(), que devuelve un constructor para configurar la transición:
Page.getCurrent().startViewTransition()
.onUpdate(done -> {
container.remove(oldView);
container.add(newView);
done.run();
})
.start();
El proceso de transición captura una instantánea del estado actual, aplica tus cambios de DOM en el callback onUpdate, y luego anima desde la instantánea antigua hacia el nuevo contenido. Debes llamar a done.run() para indicar cuándo tus cambios están completos.
onUpdate es obligatorioLlamar a start() sin establecer un callback de actualización lanza una IllegalStateException.
Aplicando transiciones
webforJ proporciona tipos de transición predefinidos que puedes aplicar a componentes al entrar o salir del DOM:
| Constante | Efecto |
|---|---|
ViewTransition.NONE | Sin animación |
ViewTransition.FADE | Fundido entre contenido antiguo y nuevo |
ViewTransition.SLIDE_LEFT | El contenido fluye a la izquierda (como una navegación hacia adelante) |
ViewTransition.SLIDE_RIGHT | El contenido fluye a la derecha (como una navegación hacia atrás) |
ViewTransition.SLIDE_UP | El contenido fluye hacia arriba |
ViewTransition.SLIDE_DOWN | El contenido fluye hacia abajo |
ViewTransition.ZOOM | El contenido antiguo se encoge, el nuevo contenido crece |
ViewTransition.ZOOM_OUT | El contenido antiguo crece, el nuevo contenido se encoge |
Usa enter() para animar un componente al ser añadido y exit() para animar un componente al ser eliminado:
// Animar un componente entrando al DOM
Page.getCurrent().startViewTransition()
.enter(chatPanel, ViewTransition.ZOOM)
.onUpdate(done -> {
container.add(chatPanel);
done.run();
})
.start();
// Animar un componente saliendo del DOM
Page.getCurrent().startViewTransition()
.exit(chatPanel, ViewTransition.FADE)
.onUpdate(done -> {
container.remove(chatPanel);
done.run();
})
.start();
Transiciones de componentes compartidos
Las transiciones de componentes compartidos crean un efecto de transformación donde un componente parece transformarse de su posición en la vista antigua a su posición en la nueva vista. Esto se logra dando a los componentes el mismo nombre de transición utilizando el método setViewTransitionName(), disponible en cualquier componente que implemente la HasStyle interfaz.
// En la vista de tarjeta
image.setViewTransitionName("blog-image");
// En la vista de detalle - el mismo nombre crea la morfosis
image.setViewTransitionName("blog-image");
Al transitar entre estas vistas, el navegador anima el componente entre posiciones, creando una experiencia visual conectada.
Al trabajar con listas o componentes repetidos, incluye un identificador único en el nombre de la transición. Cada componente requiere su propio nombre distinto para morfar correctamente a su componente correspondiente en la nueva vista. Usar el mismo nombre para múltiples componentes visibles provoca un comportamiento indefinido.
Mostrar Código
- ViewTransitionMorphView.java
- BlogCard.java
- BlogDetail.java
- morph.css
- DemoHeader.java
- demo-header.css
Reordenación de listas
Un caso de uso común para transiciones de componentes compartidos es animar elementos de lista cuando su orden cambia. Al asignar un view-transition-name único a cada ítem, el navegador anima automáticamente los componentes a sus nuevas posiciones:
// Cada tarjeta obtiene un nombre de transición único basado en su ID
card.setViewTransitionName("card-" + item.id());
// Al barajar, solo actualiza el DOM - el navegador maneja la animación
Page.getCurrent().startViewTransition()
.onUpdate(done -> {
renderList();
done.run();
})
.start();
Mostrar Código
- ViewTransitionShuffleView.java
- ShuffleCard.java
- shuffle.css
- DemoHeader.java
- demo-header.css
Animaciones CSS personalizadas
Para tener un control total sobre las animaciones, puedes definir keyframes CSS personalizados. webforJ añade sufijos -enter o -exit a tus nombres de transición, que usas para dirigirte a los pseudo-elementos de transición de vista:
/* Definir keyframes para componentes que entran */
@keyframes flip-enter {
from {
opacity: 0;
transform: perspective(1000px) rotateX(-90deg);
}
to {
opacity: 1;
transform: perspective(1000px) rotateX(0deg);
}
}
/* Aplicar al pseudo-elemento de transición de vista */
::view-transition-new(flip-in-enter) {
animation: flip-enter 450ms cubic-bezier(0.34, 1.56, 0.64, 1);
transform-origin: top center;
}
::view-transition-old(flip-in-enter) {
display: none;
}
Referencia tu animación personalizada pasando su nombre (sin el sufijo) a enter() o exit():
// Usa "flip-in" - webforJ añade automáticamente el sufijo "-enter"
Page.getCurrent().startViewTransition()
.enter(notification, "flip-in")
.onUpdate(done -> {
stage.add(notification);
done.run();
})
.start();
// Usa "blur-out" para salir - webforJ añade automáticamente el sufijo "-exit"
Page.getCurrent().startViewTransition()
.exit(notification, "blur-out")
.onUpdate(done -> {
stage.remove(notification);
done.run();
})
.start();
Mostrar Código
- ViewTransitionEnterExitView.java
- enterexit.css
- DemoHeader.java
- demo-header.css
Personalización CSS
Cada tipo de transición predefinido expone propiedades CSS personalizadas para ajustes finos:
| Variable | Predeterminado | Descripción |
|---|---|---|
--vt-fade-duration | 200ms | Duración de la animación |
--vt-fade-easing | cubic-bezier(0.4, 0, 0.2, 1) | Función de suavizado |
| Variable | Predeterminado | Descripción |
|---|---|---|
--vt-slide-left-duration | 200ms | Duración de la animación |
--vt-slide-left-easing | cubic-bezier(0.4, 0, 0.2, 1) | Función de suavizado |
--vt-slide-left-distance | 30% | Distancia de deslizamiento |
| Variable | Predeterminado | Descripción |
|---|---|---|
--vt-slide-right-duration | 200ms | Duración de la animación |
--vt-slide-right-easing | cubic-bezier(0.4, 0, 0.2, 1) | Función de suavizado |
--vt-slide-right-distance | 30% | Distancia de deslizamiento |
| Variable | Predeterminado | Descripción |
|---|---|---|
--vt-slide-up-duration | 200ms | Duración de la animación |
--vt-slide-up-easing | cubic-bezier(0.4, 0, 0.2, 1) | Función de suavizado |
--vt-slide-up-distance | 30% | Distancia de deslizamiento |
| Variable | Predeterminado | Descripción |
|---|---|---|
--vt-slide-down-duration | 200ms | Duración de la animación |
--vt-slide-down-easing | cubic-bezier(0.4, 0, 0.2, 1) | Función de suavizado |
--vt-slide-down-distance | 30% | Distancia de deslizamiento |
| Variable | Predeterminado | Descripción |
|---|---|---|
--vt-zoom-duration | 200ms | Duración de la animación |
--vt-zoom-easing | cubic-bezier(0.4, 0, 0.2, 1) | Función de suavizado |
--vt-zoom-scale | 0.8 | Factor de escala (el antiguo se aleja a esto, el nuevo se acerca desde esto) |
| Variable | Predeterminado | Descripción |
|---|---|---|
--vt-zoom-out-duration | 200ms | Duración de la animación |
--vt-zoom-out-easing | cubic-bezier(0.4, 0, 0.2, 1) | Función de suavizado |
--vt-zoom-out-scale | 1.2 | Factor de escala (el antiguo se acerca a esto, el nuevo se aleja desde esto) |
Para personalizar, sobrescribe estas variables en tu CSS:
:root {
--vt-fade-duration: 300ms;
--vt-slide-left-distance: 50%;
}
Para personalización avanzada, dirígete a los pseudo-elementos de transición de vista directamente:
::view-transition-old(vt-slide-left-exit) {
animation-duration: 400ms;
}
::view-transition-new(vt-slide-left-enter) {
animation-timing-function: ease-out;
}