Saltar al contenido principal

View Transitions

Abrir en ChatGPT
Java API
25.11 Experimental

Las transiciones de vista proporcionan transiciones animadas cuando el DOM cambia, reduciendo el choque 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 estados antiguos y nuevos.

Mostrar Código

API experimental

Esta API está marcada como experimental desde el 25.11 y puede cambiar en futuras versiones. La firma de la API, el comportamiento y las características de rendimiento están sujetos a modificación.

Uso básico

Para crear una transición de vista, utiliza 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 en el DOM en la función de devolución de llamada onUpdate, y luego anima de la instantánea antigua al nuevo contenido. Debes llamar a done.run() para señalar cuando tus cambios están completos.

La función de devolución de llamada onUpdate es obligatoria

Llamar a start() sin establecer una función de actualización lanza una IllegalStateException.

Aplicando transiciones

webforJ proporciona tipos de transición predefinidos que puedes aplicar a los componentes que entran o salen del DOM:

ConstanteEfecto
ViewTransition.NONESin animación
ViewTransition.FADETransición cruzada entre el contenido antiguo y el nuevo
ViewTransition.SLIDE_LEFTEl contenido fluye hacia la izquierda (como navegación hacia adelante)
ViewTransition.SLIDE_RIGHTEl contenido fluye hacia la derecha (como navegación hacia atrás)
ViewTransition.SLIDE_UPEl contenido fluye hacia arriba
ViewTransition.SLIDE_DOWNEl contenido fluye hacia abajo
ViewTransition.ZOOMEl contenido antiguo se reduce, el nuevo contenido crece
ViewTransition.ZOOM_OUTEl contenido antiguo crece, el nuevo contenido se reduce

Utiliza enter() para animar un componente que se está añadiendo y exit() para animar un componente que se está quitando:

// Animar un componente al entrar en el DOM
Page.getCurrent().startViewTransition()
.enter(chatPanel, ViewTransition.ZOOM)
.onUpdate(done -> {
container.add(chatPanel);
done.run();
})
.start();

// Animar un componente al salir 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 en el que un componente parece transformar su posición en la vista antigua a su posición en la vista nueva. Esto se logra al dar a los componentes el mismo nombre de transición utilizando el método setViewTransitionName(), disponible en cualquier componente que implemente la interfaz HasStyle.

// En la vista de tarjeta
image.setViewTransitionName("blog-image");

// En la vista de detalles - el mismo nombre crea la morfología
image.setViewTransitionName("blog-image");

Al transitar entre estas vistas, el navegador anima el componente entre posiciones, creando una experiencia visual conectada.

Usa nombres únicos

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 causa un comportamiento indefinido.

Mostrar Código

Reordenamiento de listas

Un caso de uso común para las transiciones de componentes compartidos es animar los elementos de una lista cuando su orden cambia. Al asignar un view-transition-name único a cada artículo, el navegador anima automáticamente los componentes a sus nuevas posiciones:

// Cada tarjeta recibe un nombre de transición único basado en su ID
card.setViewTransitionName("card-" + item.id());

// Al mezclar, solo actualiza el DOM - el navegador maneja la animación
Page.getCurrent().startViewTransition()
.onUpdate(done -> {
renderList();
done.run();
})
.start();
Mostrar Código

Animaciones CSS personalizadas

Para 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 utilizas 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

Personalización CSS

Cada tipo de transición predefinido expone propiedades CSS personalizadas para afinamiento:

VariablePredeterminadoDescripción
--vt-fade-duration200msDuración de la animación
--vt-fade-easingcubic-bezier(0.4, 0, 0.2, 1)Función de easing
VariablePredeterminadoDescripción
--vt-slide-left-duration200msDuración de la animación
--vt-slide-left-easingcubic-bezier(0.4, 0, 0.2, 1)Función de easing
--vt-slide-left-distance30%Distancia de deslizamiento
VariablePredeterminadoDescripción
--vt-slide-right-duration200msDuración de la animación
--vt-slide-right-easingcubic-bezier(0.4, 0, 0.2, 1)Función de easing
--vt-slide-right-distance30%Distancia de deslizamiento
VariablePredeterminadoDescripción
--vt-slide-up-duration200msDuración de la animación
--vt-slide-up-easingcubic-bezier(0.4, 0, 0.2, 1)Función de easing
--vt-slide-up-distance30%Distancia de deslizamiento
VariablePredeterminadoDescripción
--vt-slide-down-duration200msDuración de la animación
--vt-slide-down-easingcubic-bezier(0.4, 0, 0.2, 1)Función de easing
--vt-slide-down-distance30%Distancia de deslizamiento
VariablePredeterminadoDescripción
--vt-zoom-duration200msDuración de la animación
--vt-zoom-easingcubic-bezier(0.4, 0, 0.2, 1)Función de easing
--vt-zoom-scale0.8Factor de escala (el antiguo se aleja a esto, el nuevo se acerca desde esto)
VariablePredeterminadoDescripción
--vt-zoom-out-duration200msDuración de la animación
--vt-zoom-out-easingcubic-bezier(0.4, 0, 0.2, 1)Función de easing
--vt-zoom-out-scale1.2Factor de escala (el antiguo se acerca a esto, el nuevo se aleja de esto)

Para personalizar, sobrescribe estas variables en tu CSS:

:root {
--vt-fade-duration: 300ms;
--vt-slide-left-distance: 50%;
}

Para personalización avanzada, dirige 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;
}