Wzorzec 19
Przejście zamiast teleportacji
Po filtrowaniu listy użytkownik traci z oczu kartę, na którą patrzył, bo wszystko zmienia miejsce w jednej klatce. document.startViewTransition robi zrzut starego stanu, wprowadza nowy i animuje różnicę, a view-transition-name mówi przeglądarce, które elementy są tym samym bytem.
Filtruj i tasuj, nie gubiąc kart z oczu
Każda karta ma view-transition-name, więc przy zmianie kolejności płynie na nowe miejsce, zamiast teleportować się w jednej klatce. Filtrowanie wygasza znikające karty i wprowadza wracające.
Atlas
Branding
Heliotrop
Aplikacja
Novak
E-commerce
Wrzos
Branding
Akademia
Aplikacja
Magazyn
E-commerce
Siatka rezerwuje wysokość pełnego zestawu, więc filtrowanie nie rusza treści pod demo. Bez wsparcia przeglądarki i przy reduced motion ta sama funkcja aktualizuje stan natychmiast.
Reguły
- Zmianę stanu opakowuje document.startViewTransition, reszta kodu zostaje bez zmian.
- Każdy przenoszony element ma unikalny view-transition-name, więc płynie, zamiast znikać i wracać.
- Brak wsparcia degraduje do natychmiastowej zmiany: ta sama funkcja aktualizuje stan z przejściem i bez.
- prefers-reduced-motion pomija przejście i wprowadza nowy stan od razu.
Wzorzec w kodzie
function withTransition(update: () => void) {
const reducedMotion = matchMedia(
"(prefers-reduced-motion: reduce)",
).matches;
if (!document.startViewTransition || reducedMotion) {
update();
return;
}
document.startViewTransition(() => {
flushSync(update);
});
}<div style={{ viewTransitionName: `karta-${project.id}` }}>
{project.name}
</div>