2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AstroAdvent Calendar 2024

Day 12

AstroでView Transitionsを利用したときの挙動に少し気を遣う

Last updated at Posted at 2024-12-11

この記事の概要

View Transitions APIを使った画面遷移はスムーズで見栄えも良いです。

ただしtransitionの対象が画面外にあると一瞬表示崩れにも見える挙動をします。

上記の内容に対する、Astroでの解消方法を記事にしました。

起きることと、対処した後の結果

次のgifでは以下の操作をしています

  1. ページ遷移→すぐさま(= transition対象が画面内にある状態で)ブラウザバック
  2. ページ遷移→スクロールし(= transition対象が画面内にない状態で)ブラウザバック

transition対象が画面内にない状態でのブラウザバックでは、画面外から画像が降ってくるような挙動になっており、やや違和感があります。

これを、次のように「transition対象が画面内にない状態で遷移した場合、単なるディゾルブ効果」に変更します。

やること

遷移させるにあたって、次のようなコードがあるはずです。

<div transition:name={someName}>何かしらの要素</div>

AstroでView Transitionsを実装する方法自体はこの記事では触れません。公式ドキュメントなどをご覧ください。

遷移対象の要素にidを付与します。

- <div transition:name={someName}>何かしらの要素</div>
+ <div id="something" transition:name={someName}>何かしらの要素</div>

その上で以下のコードを追加します。

<script>
  function setupImageTransition() {
    const somethingElement = document.querySelector("#something");
    if (!somethingElement) return;

    const initialScope = somethingElement.getAttribute("data-astro-transition-scope");
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting && initialScope) {
            somethingElement.setAttribute("data-astro-transition-scope", initialScope);
          } else {
            somethingElement.removeAttribute("data-astro-transition-scope");
          }
        });
      },
      {
        threshold: 0.1,
      },
    );

    observer.observe(somethingElement);
  }

  document.addEventListener("astro:page-load", setupImageTransition);
</script>

ポイントは2点です。

  1. setAttribute, removeAttributeする対象はtransition:nameではなくdata-astro-transition-scope
  2. initialScopeとして最初の状態のdata-astro-transition-scopeを保持しておく

setAttribute, removeAttributeする対象はtransition:nameではなくdata-astro-transition-scope

Astroに同一要素として判断してもらうためにはtransition:nameを記載する必要があります。
しかし、この値そのもので同一化を判断しているわけではありません。
この値をもとにして生成されたdata-astro-transition-scopeが判断材料です。

removeAttributetransition:nameを消しても、既にdata-astro-transition-scopeが付与されてしまっており、最初に貼ったgifから動きは変わりません。
そのためdata-astro-transition-scopeを操作します。

initialScopeとして最初の状態のdata-astro-transition-scopeを保持しておく

当たり前ですが、一度data-astro-transition-scopeを削除したら、単にsetAttributeしたところで値は戻ってきません。

そのため、最初のdata-astro-transition-scopeを保持しておく必要があります。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?