View TransitionsとNext.js:ライブラリなしのページアニメーション
View TransitionsとNext.js:ライブラリなしのページアニメーション
View Transitions APIはそのトリックをあなたから取り上げ、ブラウザに渡します。2つの生きたDOMツリーを保持して測定する代わりに、ブラウザが古い状態のスナップショットを撮り、DOMを更新し、新しい状態のスナップショットを撮り、その2枚の画像の間をアニメーションさせます — コンポジターで。
javascript
function navigate(update) {if (!document.startViewTransition) {update(); // 非対応:更新のみ、アニメーションなしreturn;}document.startViewTransition(() => update());}
css
::view-transition /* ページ全体を覆うオーバーレイ */::view-transition-group(name) /* サイズと位置をアニメーション */::view-transition-image-pair(name)::view-transition-old(name) /* "前"のスナップショット */::view-transition-new(name) /* "後"のスナップショット */
誰もが驚くこと:スナップショットは写真であり、要素ではない
::view-transition-oldは古い要素を縮小したものではありません。それは静止画像です。<video>は1フレームで止まります。ローディングスピナーは回転を止めます。200msではそれは問題になりません。1000msでは明らかです。
命名:契約の全て
css
.card-image {view-transition-name: hero;}::view-transition-group(hero) {animation-duration: 400ms;animation-timing-function: ease-in-out;}
厳しいルール:view-transition-nameはいかなる時もドキュメント内で一意でなければなりません。
React 19.2とNext.js 16:一つのコンポーネント
tsx
import { ViewTransition } from "react";import Image from "next/image";import Link from "next/link";export function ProjectCard({ project }) {return (<Link href={"/projects/" + project.slug}><ViewTransition name={"project-" + project.slug}><Image src={project.cover} alt={project.title} /></ViewTransition></Link>);}
shareとdefault="none"はセットで使う必要があります。default="none"でshareプロップなしの場合、名前付きペアは静かにモーフィングを停止します。
方向:ユーザーにどちらに進んだかを伝える
tsx
<Link href="/projects/runvalis" transitionTypes={["nav-forward"]}>Runvalis</Link><ViewTransitionenter={{ "nav-forward": "slide-in", "nav-back": "slide-out", default: "none" }}exit={{ "nav-forward": "slide-out", "nav-back": "slide-in", default: "none" }}default="none"><main>{children}</main></ViewTransition>
フレームワークなしのバージョン
css
@view-transition {navigation: auto;}
落とし穴とベストプラクティス
- 常にプログレッシブエンhancementとして扱う。
- スローモーションでデバッグする。
prefers-reduced-motionを尊重する。- オーバーレイはデフォルトでクリックを消費する。
- スナップショットはメモリを消費する。
- ヘッダーをアンカーする。
- ビュートランジションは支援技術には見えない。
まとめ
View Transitionsはナビゲーションに適用された同じ議論です:FLIPを手で実行する代わりに、2つの状態を結ぶものを宣言し、ブラウザに2枚の写真からつながりを描かせます。