View Transitions Snippets: Getting all Animations linked to a View Transition

~

🌟 This post is about View Transitions. If you are not familiar with the basics of it, check out this 30-min talk of mine to get up to speed.

~

With this snippet you can get all animations that are linked to an active View Transition:

const vtAnimations = document.getAnimations().filter((anim) => {
  return anim.effect.target === document.documentElement &&
      anim.effect.pseudoElement?.startsWith("::view-transition")
});

This gets all animations for the document and filters out those that are linked to a pseudo element of document.documentElement whose name starts with "::view-transition"

~

You run this code after you have started the transition and after the snapshots have been taken:

// Start a View Transition
const t = document.startViewTransition(…);
    
// Wait for the snapshots to be taken
await t.ready;

// Get all animations
const vtAnimations = document.getAnimations().filter((anim) => {
  return anim.effect.target === document.documentElement &&
      anim.effect.pseudoElement?.startsWith("::view-transition")
});

~

Once you have the animations, you can do all sorts of things with them: reverse them, change the duration, change the keyframes themselves, etc.

In the following example I get the keyframes for the ::view-transition-group(box) pseudo and dump them on screen to see what’s going on.

See the Pen
Debugging View Transitions: Getting the group’s animation
by Bramus (@bramus)
on CodePen.

The core of the code is the following:

// Get the animation linked to '::view-transition-group(box)'
const boxGroupAnimation = vtAnimations.find((anim) => {
  return anim.effect.pseudoElement == '::view-transition-group(box)';
});

// Get the keyframes
const boxKeyframes = boxGroupAnimation.effect.getKeyframes();

👆 This demo is extra interesting because it surfaces bugs with getKeyframes() for ::view-transition-group() pseudos in both Blink and WebKit: Blink computes the wrong to keyframe (bug) and WebKit exposes the wrong from keyframe (bug).

Or check out this demo by Jake Archibald – where I got the code originally from – that pauses all animations and updates their currentTime based on the drag distance as you drag the grey circle from side to side.

The result is a Draggable View Transition, but more on that in a later post 😉

(Check out Jake’s demo in Chrome for full effect, as it uses the Navigation API which is not in Safari stable yet)

~

In the future you should be able to simplify the code to the following, thanks to w3c/csswg-drafts#9908.

// 🔮 Code from the future. This does not work in any browser … yet.
const vtAnimations = t.transitionRoot.getAnimations({
  pseudoElement: '::view-transition',
  subtree: true,
});

It calls getAnimations() on the transition root directly – handy whenever scoped transitions becomes a thing – and uses the new pseudoElement option to filter out the ::view-transition overlay pseudo. With subtree: true, all children of that pseudo are also included in the resultset.

This code however still needs to be specced and is currently not implemented in any browser. Until then, use the code shared at the top of this post.

~

# Spread the word

Feel free to repost one of my posts on social media to give them more reach, or link to the blogpost yourself one way or another 🙂

~

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Unless noted otherwise, the contents of this post are licensed under the Creative Commons Attribution 4.0 License and code samples are licensed under the MIT License

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.