前回は、CSS Gridを活用して9枚のタロットカードを画面上に美しく整列させ、ユーザーに「直感で選ばせる」ためのUIを構築しました。しかし、ユーザーがカードをタップした瞬間に、パッと一瞬で結果画面に切り替わってしまっては、せっかくの神秘的な雰囲気が台無しになってしまいます。
第9回となる今回は、このアプリにおける最大のハイライトとも言える「タップしたカードがフワッとめくれる演出」と「結果画面への滑らかな遷移」を実装していきます。ここで、Webアプリを一段上のクオリティへ引き上げる強力な魔法の杖が登場します。
魔法の杖「Framer Motion」の導入
複雑なアニメーションをゼロからCSSで記述するのは、非常に高度で骨の折れる作業です。そこで今回は、React向けのアニメーションライブラリである「Framer Motion(フレーマーモーション)」を活用します。
このライブラリの素晴らしいところは、動きをつけたい要素(画面のパーツ)を専用のタグ(たとえば <motion.div>)で囲み、「最初の状態(initial)」「変化後の状態(animate)」「変化にかかる時間(transition)」の3つを文字で指定するだけで、あとはシステムが間のコマを自動的に計算して、恐ろしいほど滑らかなアニメーションを描画してくれる点にあります。
3D空間でカードを裏返す「フリップアニメーション」
ユーザーが9枚の中から1枚を選んでタップしたとき、まずはその選ばれたカードが画面の中央へとフワッと浮かび上がり、大きく拡大される動きを作ります。
そして、最も重要な「めくれる(裏返る)」演出です。
これは、画面上に「カードの裏面」と「引いた結果の表面(第6回で作成したランダムドローの結果)」の2枚の画像を背中合わせに重ねて配置することで実現します。そして、Framer Motionを使ってこのまとまりをY軸(縦の軸)を基準に「180度回転(rotateY)」させます。
このとき、CSSの「裏面を非表示にする(backface-visibility: hidden)」という性質を組み合わせておくことで、回転の途中で裏面の画像が見えなくなり、シームレスに表面のタロット画像が現れるという、まるで手品のような美しい3Dフリップが完成するのです。
没入感を途切れさせない「クロスフェード」の画面遷移
カードが完全にめくれ終わると、いよいよカードの意味や解説文が表示される「結果画面」へと移動します。
通常のWebサイトのように、一瞬で画面が切り替わってしまうと、これまでの神秘的な没入感が途切れてしまいます。そこで、画面全体がゆっくりと溶け合うように切り替わる「クロスフェード」という演出を取り入れます。
選択画面がゆっくりと透明になって消えていく(フェードアウト)と同時に、結果のテキストや「もう一度占う」ボタンを含んだ結果画面が、同じ位置でゆっくりと浮かび上がってくる(フェードイン)ように設定します。
実は開発段階では、この切り替えの瞬間に「画面がカクッと一瞬下にズレる」というレイアウト崩れが起きやすいのですが、画面全体を「絶対配置(absolute)」にして同じ座標にピタッと重ね合わせることで、不透明度(opacity)だけが純粋に入れ替わる、極めて美しい遷移を実現できました。
次回(第10回)は、ついに最終回です。アプリアイコンの設定や細部のブラッシュアップを行い、完成したアプリを再びCloudflareへとデプロイする「本当の公開」の瞬間をお届けします!
【編集後記】
タップしたカードが滑らかに中央へ移動し、クルッと美しい弧を描いて裏返った瞬間。そして、それに続くテキストが静かに画面に浮かび上がったとき、ただの「Webページ」が、命を持ったひとつの「体験(エクスペリエンス)」へと昇華したのを肌で感じました。Framer Motionのなめらかな60fps(1秒間に60コマ)の動きは、何度見ても飽きないほどの心地よさがあります。プログラミングにおいて、こうした「触っていて気持ちいい」という感覚を作り出せるのは、フロントエンド開発の最大の特権であり、至福の喜びですね。
