🚀 🔔 🎁 🚀 🐧

Technical information about this demo

Snowflakes, gift box, penguin, bell, and rocket define their own groups in this view transition. The icons are also on this second page, but with different positions, sizes and transforms. You might find them when you scroll this page further down. Thus on browsers that implement view transitions, the default morph animation of the view transition lets them fly out. As they fly away, they retain their original animations.

The snowflakes have different animation durations and delays, so they fly out at different speeds and times.

It is important that the CCS for the view transition to /winter/two/ is included in that second page, as the visual effects of the transition only begin after the DOM has been switched to the target page. In the same way, the CSS definitions for the navigation to /winter/one/ are defined in /winter/one/. If you click on “Back” in the browser, you will see a faster transition where all symbols have the same start and duration.

The falling tree and snowboarder are custom animations that run directly before the view transition. They are triggered by the event listener for the astro:before-preparation event.

winter.astro
document.addEventListener('astro:before-preparation', (event) => {
if (isTransitionBeforePreparationEvent(event)
&& event.from.pathname.endsWith('/winter/one/')) {
const originalLoader = event.loader;
event.loader = async () => {
await Promise.all([
originalLoader(),
fade(document.getElementById('tree')),
fade(document.getElementById('snowboarder')),
]);};}});

The astro:before-preparation event can execute asynchronous actions. The original loader() activity, which retrieves the DOM of the target page, is replaced by a function that executes the animations in parallel with the original loader and waits until all three actions have been completed.

The animations of the star and the sliding section on this page are independent of the view transition. They are triggered by inserting the new HTML elements when the new DOM is swapped in.