トップページに、マイルームセクションとして3Dアイソメトリックルームとレコードラックを実装しました。(ほとんどGeminiにお任せですが)
こんにちは、 junprog です。
今回、トップページのビジュアルを一新し、以下の2つのインタラクティブなコンポーネントを導入しました。
- 3Dアイソメトリックルーム(部屋のイラストと所持ガジェットの連動)
- レコードラック(保有しているLP紹介スライダー)
見た目の楽しさだけでなく、モバイル環境でも「ガタツキ感」のないスムーズな操作性を実現するためのパフォーマンス最適化にもかなりこだわったので、技術的なポイントを振り返ります。
1. 3Dアイソメトリックルーム
概要
私の愛用ガジェットが配置されいてる部屋のイラストがアイソメトリックで描かれたコンポーネントです。
- 仕様
- 部屋の中にガジェット(HHKB、自作PC、カメラやレンズなど)が配置され、そこから引き出された動的なコネクションがガジェットの名前を指してブログ記事があればリンクを提供しています。
- データ構造の分離
- メンテナンス性を考慮し、ガジェットの位置情報(パーセンテージベースの座標)やブログ記事へのリンクは外部JSONファイルに切り出して一元管理するようにしました。
- ダークモード対応
- ダークモードのときに、イラストの部屋が暗くなり照明がつくようなデザインにしてみました。
- ただ、ガジェットを増やしたいときにライトモードとダークモードとでイラストの一貫性を保つようにAIに描いてもらうのが大変なので、要改善です。
モバイル向け最適化のポイント
デスクトップではホバー時にガジェットの名前がふわふわと浮遊するアニメーション(CSS Keyframe Animation)が動きます。しかし、モバイル画面でもこのアニメーションを実行し、かつ画面上に引き出されるSVGの線を毎フレーム requestAnimationFrame で再計算(getBoundingClientRect() による座標取得)し続けると、レイアウトスラッシング(Forced Reflow)が発生し、スクロールが重くなる原因になります。
そこで、モバイル(画面幅768px以下)では以下の最適化を施しました:
- CSSアニメーションの無効化
- CSSメディアクエリで浮遊アニメーションを
none !importantに。
- CSSメディアクエリで浮遊アニメーションを
- 描画ループのスキップ
- JS側でモバイル viewport を判定し、接続線を再計算するフレームループへの登録自体をスキップ。
パーセンテージベースの静的な座標指定により、JSを一切動かさなくてもモバイル上で線とラベルが完璧に揃うようになり、モバイルでのCPU負荷をゼロに抑えました。
2. レコードラック
概要
私が保有しているLPを紹介するコンポーネントです。
ラックに収納されたレコードを指でパラパラと掘る動作をブラウザ上に表現しました。
- 立体的な3D表現:
- 通常時(非アクティブ時)は、レコードが斜め手前に傾いた状態(
transform: skewY(-15deg) scaleX(0.3))で隙間なく並んでいます。 - スクロールして画面中央に来たアルバム(アクティブ)は、立体的な傾きからすっと真っ直ぐに開き、さらに右側から黒いレコード盤(ビニール)がスライドアウトします。
- 左右のレコードは、アクティブ盤が開くスペースを空けるため、自動的に左右対称にスライドして避ける挙動(
is-pastは左へ、is-futureは右へ)をとります。
- 通常時(非アクティブ時)は、レコードが斜め手前に傾いた状態(
- 透明レコードプレースホルダー:
- 一番右端には、次に紹介したいレコード用の「More to come…」という破線仕様のカードを配置。
- こちらも中央に来た際には、クリア(半透明)のガラス風ビニール盤が美しくスライドアウトする遊び心を加えました。
- データ構造の分離
- アイソメトリックルームと同様に、メンテナンス性を考慮してレコードの情報を外部JSONファイルに切り出して一元管理するようにしました。
パフォーマンスと「ガタツキ感(Jitter)」の解消
初期の実装ではタッチスワイプ操作をJSのイベントリスナーでハンドリングして手動でスクロール位置を制御していたため、モバイル端末で操作した際に指の動きに追従せず、ガタツキが発生していました。
これを解消するために、以下のドラスティックなアプローチを取りました:
- ネイティブスクロール & CSS Snap の採用:
- JSによるスワイプの乗っ取りを全て廃止。
- ブラウザ標準のハードウェアアクセラレーションが効く
overflow-x-autoとsnap-x snap-mandatory(CSS Scroll Snap)に置き換えました。これにより、モバイルのシステムに最適化されたスムーズな慣性スクロールが100%機能します。
- モバイル用のサイズ最適化:
- スマートフォンなどの小さな画面では、レコードジャケットサイズを
w-40(160px)からw-32(128px) へと一回り小さく設計。 - レコードが小さくなった分、避ける隙間(
translateXのオフセット値)やセンターへのアライメントの計算式を再調整し、完璧に対称なグリッドを保つようにしました。
- スマートフォンなどの小さな画面では、レコードジャケットサイズを
- ナビゲーションボタンのレスポンシブ化:
- デスクトップだけでなく、モバイル表示時にもタッチフレンドリーな小型の丸型矢印ボタン(横幅40px)を配置し、タップ操作でも快適にレコードを切り替えられるようにしました。
まとめ
今回のリニューアルを通じて、Astroの高速な表示速度は維持したまま、動きがあって触って楽しいトップページを作ることができました。
特にアニメーションや3D表現は、モバイル表示を「ただ非表示にする」のではなく、「表示させたまま、実行される処理(計算・CSS)を最小限に抑えることでヌルヌル動かす」というアプローチを取ることで、パフォーマンスと表現力の両立ができたと感じています。
ぜひ新しくなったトップページで、遊んでみてください!