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 desajuste 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 los estados antiguos y nuevos.

Mostrar Código

Característica experimental
Esta función es experimental y puede cambiar o eliminarse en una versión futura.

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 en el DOM en la devolución de llamada onUpdate, y luego anima desde la instantánea antigua al nuevo contenido. Debes llamar a done.run() para señalizar cuándo tus cambios están completos.

La devolución de llamada onUpdate es obligatoria

Llamar a start() sin establecer una devolución de llamada de actualización lanza un 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.FADEDesvanecimiento 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 encoge, el contenido nuevo crece
ViewTransition.ZOOM_OUTEl contenido antiguo crece, el contenido nuevo se encoge

Usa enter() para animar un componente al ser agregado y exit() para animar un componente al ser removido:

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

// Animar un componente que sale 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 desde 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 interfaz HasStyle.

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

// En la vista de detalle - 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 comportamientos indefinidos.

Mostrar Código

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 elemento, 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 barajar, 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 tener 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 el sufijo "-enter" automáticamente
Page.getCurrent().startViewTransition()
.enter(notification, "flip-in")
.onUpdate(done -> {
stage.add(notification);
done.run();
})
.start();

// Usa "blur-out" para la salida - webforJ añade el sufijo "-exit"
Page.getCurrent().startViewTransition()
.exit(notification, "blur-out")
.onUpdate(done -> {
stage.remove(notification);
done.run();
})
.start();
Mostrar Código

Personalización de CSS

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

VariablePredeterminadoDescripción
--vt-fade-duration200msDuración de la animación
--vt-fade-easingcubic-bezier(0.4, 0, 0.2, 1)Función de suavizado
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 suavizado
--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 suavizado
--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 suavizado
--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 suavizado
--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 suavizado
--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 suavizado
--vt-zoom-out-scale1.2Factor 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;
}