~
🌟 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 🙂
~
🔥 Like what you see? Want to stay in the loop? Here's how: