Next route/WORK
INTERACTION_159CSS + JS
Curtain Transition
Panels close over the page then lift to reveal the next route.
Transitions / LightView
A circle grows from the click point to cover the page. Scale 0 at the pointer coordinates before the trigger; scaling the circle until it covers the viewport, then swapping content once clicking a navigation control.
/* Expanding Circle Transition — A circle grows from the click point to cover the page. */
.expanding-circle-transition {
--dur: 620ms;
--ease: cubic-bezier(0.22, 1, 0.36, 1);
--stagger: 60ms;
will-change: transform, opacity;
}
.expanding-circle-transition > * {
opacity: 0;
transform: translateY(14px);
animation: expanding-circle-transition-in var(--dur) var(--ease) forwards;
animation-delay: calc(var(--i, 0) * var(--stagger));
}
/* scale 0 at the pointer coordinates -> scaling the circle until it covers the viewport, then swapping content */
@keyframes expanding-circle-transition-in {
to {
opacity: 1;
transform: none;
filter: none;
}
}
@media (prefers-reduced-motion: reduce) {
.expanding-circle-transition > * {
opacity: 1;
transform: none;
animation: none;
}
}import { useEffect, useRef } from "react";
/** Expanding Circle Transition — trigger: clicking a navigation control */
export function ExpandingCircleTransition({ children }: { children: React.ReactNode }) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
el.dataset["state"] = "in";
return;
}
const io = new IntersectionObserver(
([entry]) => {
if (entry?.isIntersecting) {
el.dataset["state"] = "in";
io.unobserve(el);
}
},
{ threshold: 0.2 },
);
io.observe(el);
return () => io.disconnect();
}, []);
return (
<div ref={ref} className="expanding-circle-transition" data-state="out">
{children}
</div>
);
}Panels close over the page then lift to reveal the next route.
The outgoing page blurs out and the next resolves into focus.
Routes slide horizontally in the direction of travel.
A curved wipe sweeps across the screen between pages.