From 7a894eec3e6d2670632ca8cdb592cf5649a22d3e Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Thu, 31 Aug 2023 13:32:45 -0400 Subject: [PATCH] Prevent View Transition fallback from waiting on looping animations (#8331) * Prevent View Transition fallback from waiting on looping animations * Filter out infinite animations --- .changeset/late-foxes-juggle.md | 5 +++++ packages/astro/components/ViewTransitions.astro | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 .changeset/late-foxes-juggle.md diff --git a/.changeset/late-foxes-juggle.md b/.changeset/late-foxes-juggle.md new file mode 100644 index 000000000000..54374f2e42b9 --- /dev/null +++ b/.changeset/late-foxes-juggle.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Prevent View Transition fallback from waiting on looping animations diff --git a/packages/astro/components/ViewTransitions.astro b/packages/astro/components/ViewTransitions.astro index ea56a60b98bf..29fe5dd1fccd 100644 --- a/packages/astro/components/ViewTransitions.astro +++ b/packages/astro/components/ViewTransitions.astro @@ -98,6 +98,17 @@ const { fallback = 'animate' } = Astro.props as Props; return wait; } + function isInfinite(animation: Animation) { + const effect = animation.effect; + if( + !effect || + !(effect instanceof KeyframeEffect) || + !effect.target + ) return false; + const style = window.getComputedStyle(effect.target, effect.pseudoElement); + return style.animationIterationCount === "infinite"; +} + const parser = new DOMParser(); async function updateDOM(html: string, state?: State, fallback?: Fallback) { @@ -221,8 +232,10 @@ const { fallback = 'animate' } = Astro.props as Props; if (fallback === 'animate') { // Trigger the animations + const currentAnimations = document.getAnimations(); document.documentElement.dataset.astroTransitionFallback = 'old'; - const finished = Promise.all(document.getAnimations().map(a => a.finished)); + const newAnimations = document.getAnimations().filter(a => !currentAnimations.includes(a) && !isInfinite(a)); + const finished = Promise.all(newAnimations.map(a => a.finished)); const fallbackSwap = () => { swap(); document.documentElement.dataset.astroTransitionFallback = 'new';