The ready
read-only property of the ViewTransition
interface is a Promise
that fulfills once the pseudo-element tree is created and the transition animation is about to start.
ready
will reject if the transition cannot begin. This can be due to misconfiguration, for example duplicate view-transition-name
s, or if the callback passed to Document.startViewTransition()
throws or returns a promise that rejects.
In the following example, ready
is used to trigger a custom circular reveal view transition emanating from the position of the user's cursor on click, with animation provided by the Web Animations API.
let lastClick;
addEventListener("click", (event) => (lastClick = event));
function spaNavigate(data) {
if (!document.startViewTransition) {
updateTheDOMSomehow(data);
return;
}
const x = lastClick?.clientX ?? innerWidth / 2;
const y = lastClick?.clientY ?? innerHeight / 2;
const endRadius = Math.hypot(
Math.max(x, innerWidth - x),
Math.max(y, innerHeight - y),
);
const transition = document.startViewTransition(() => {
updateTheDOMSomehow(data);
});
transition.ready.then(() => {
document.documentElement.animate(
{
clipPath: [
`circle(0 at ${x}px ${y}px)`,
`circle(${endRadius}px at ${x}px ${y}px)`,
],
},
{
duration: 500,
easing: "ease-in",
pseudoElement: "::view-transition-new(root)",
},
);
});
}
This animation also requires the following CSS, to turn off the default CSS animation and stop the old and new view states from blending in any way (the new state "wipes" right over the top of the old state, rather than transitioning in):
::view-transition-image-pair(root) {
isolation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
display: block;
}