View Transition APIとは
MDN Web docによると
ビュートランジション API は、異なる DOM 状態間のアニメーション遷移を簡単に作成する仕組みを提供し、同時に DOM コンテンツも単一の手順で更新します。
とのことです。つまりスマートフォンアプリなどで一般的なスムーズな遷移表現のWeb版ですね。
SvelteKitとView Transition API
SvelteKitとView Transition APIについてはSvelte.devのBlog記事に記載の通り、SvelteKit 1.24で実装されたonNavigateライフサイクルで利用可能になりました。
以下のコードはページ遷移時にクロスフェード効果を適用します。
onNavigate((navigation) => {
if (!document.startViewTransition) return;
return new Promise((resolve) => {
document.startViewTransition(async () => {
resolve();
await navigation.complete;
});
});
});
僅かなCSSの記述とスニペットを使えばクロスフェード以外にも色々な遷移効果が実現できますが、もっと簡単に使いたいですよね。
sveltekit-view-transitionを使えばいい
sveltekit-view-transition はSvelteKitでView Transition APIをより簡単に利用できるライブラリです。
準備
プロジェクトの準備
今回の動作確認用に簡単なページ遷移を備えたプロジェクトを作りました。
sveltekit-view-transition のインストール
$ npm i -D sveltekit-view-transition@latest
使い方
クロスフェード効果
以下のコードをルートlayoutなどに追記するだけで内部のページ遷移にクロスフェード効果が適用されます。とても簡単ですね。
<script>
import { setupViewTransition } from 'sveltekit-view-transition';
setupViewTransition();
</script>
スライド効果
古いページが左へスライドしながらフェードアウトしてゆき、新しいページが右からフェードインします。前述のクロスフェード効果に下記のCSSでカスタムします。
@keyframes fade-in {
from {
opacity: 0;
}
}
@keyframes fade-out {
to {
opacity: 0;
}
}
@keyframes slide-from-right {
from {
transform: translateX(100px);
}
}
@keyframes slide-to-left {
to {
transform: translateX(-100px);
}
}
:root::view-transition-old(root) {
animation:
90ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
}
:root::view-transition-new(root) {
animation:
210ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
}
要素のトランジション
クリックした画像が遷移先の画像へと遷移するアレです。
遷移元、遷移先の要素それぞれにuse:transitionで設定することで、同じ名前の要素同士が連動するようになります。
遷移元
<script>
import { setupViewTransition } from 'sveltekit-view-transition';
const { transition } = setupViewTransition();
</script>
<div class="grid grid-cols-3 gap-8">
{#each Array(6) as _, i}
<a href="/description/{i + 1}" use:transition={`image${i + 1}`}>
<img
class="rounded-xl shadow-xl"
src="https://example.com/pic{i + 1}.png"
alt="pic-{i}"
/>
</a>
{/each}
</div>
遷移先
<script>
import { page } from '$app/stores';
import { setupViewTransition } from 'sveltekit-view-transition';
const { transition } = setupViewTransition();
</script>
<img
use:transition={`image${$page.params.img_no}`}
src="https://example.com/pic{$page.params.img_no}.png"
alt="pic-{$page.params.img_no}"
/>
まとめ
View Transitionは見た目が華やかになるだけではなく、要素の連続性を表現することでUXを高める効果もあります。SvelteKitを使用する際はぜひsveltekit-view-transition を使用して効果的なView Transitionを適用してみてはいかがでしょうか。
参考
https://svelte.dev/blog/view-transitions
https://github.com/paoloricciuti/sveltekit-view-transition
https://developer.mozilla.org/ja/docs/Web/API/View_Transitions_API
https://developer.chrome.com/docs/web-platform/view-transitions/