E.D.E.N.開発ログ #7|画面サイズで崩れたAI画面を、ワイド・縦置き・スマホに対応させた

E.D.E.N.をワイド画面で表示した状態 開発ログ

E.D.E.N.という、わたし専用のAIアシスタントを作っています。従量課金のAPIを増やさず、手元のPCで動かすことを条件にしているプロジェクトです。

ブラウザで開く画面なので、見る場所によって画面の形が変わります。横長のモニター、縦に置いたモニター、スマホ。最初の作りでは、画面の比率が変わると中央の表示が拡大されたり、切れたりしていました。今回はそれを直した記録です。

何が崩れていたか

当初、画面の中央には人物の画像を置いていました。この画像が、画面の比率によって拡大されたり、端で切られたりしていました。

そこで人物画像はやめて、中央を「コア」と呼んでいる抽象的な図形に置き換えました。同心円、72本の放射線、42個の粒子、多角形、光る核でできていて、Canvas(ブラウザで図形を描く仕組み)に描いています。大きさは画像のように固定せず、画面の寸法から毎フレーム計算します。画像を引き伸ばすのではなく、その場の大きさで描き直すので、比率が変わっても切れません。

ただ、コアだけ直しても、画面全体の並びが1種類のままでは足りませんでした。

画面の大きさを基準に、並びを4通りにした

レイアウトは、画面(ビューポート)の幅・高さ・向きで切り替えるCSSにまとめました。実際の区切りは次のとおりです。

条件 並び
通常(横長) 3列。左にモード選択、中央にコア、右に対話
幅1100px以下、または縦向き モード選択を上に横並びにし、その下を2列に
縦向き、かつ幅701px以上 1列。上段にコア、下段に対話
幅700px以下 1列。コアは高さ140〜220pxに縮め、対話を広く取る

ほかに、幅2200px以上の大きな画面では対話欄を広げ、高さ550px以下の横長画面では見出しを省いて詰める指定も入れています。

もう1つ決めたのは、画面そのものはスクロールさせないことです。画面全体の高さを表示領域の高さに固定し、スクロールするのは対話のログや一覧の中身だけにしました。長い会話をしても、コアや入力欄が画面の外へ流れていきません。

ワイド(1600×900)で開いた状態です。

E.D.E.N.をワイド画面で表示した状態。左にモード選択、中央に円形のコア、右に対話パネルの3列

縦置き(900×1400)では、上段にコア、下段に対話が並びます。モード選択は一番上に横並びになります。

E.D.E.N.を縦長の画面で表示した状態。上にモード選択、その下にコア、下半分に対話パネル

スマホ(390×844)では、コアを小さくして、対話の欄を広く取っています。

E.D.E.N.をスマホ幅で表示した状態。小さくしたコアの下に対話ログと入力欄

この3つの大きさで、コアを描いているCanvasの表示寸法を測りました。

画面 Canvasの表示寸法 横スクロール
ワイド 1600×900 728×756 なし
縦置き 900×1400 532×497 なし
スマホ 390×844 204×192 なし

どの大きさでも、ページの横幅は画面の幅と一致していて、横にはみ出していませんでした。

詰まったところ1: 並びを直したら、円が消えた

レイアウト用のCSSを足したあと、コアの一部が表示されなくなりました。原因は、そのCSSの中で、コアを構成する層の1つを誤って非表示にしていたことです。

小さい画面では要素を減らすために、いくつかの部品を非表示にしています。その指定が、消してはいけない層にもかかっていました。見た目の崩れを直すつもりで、別のものを消していたことになります。この指定を外して、層を復旧しました。

詰まったところ2: 円が描かれない原因は、初期化前の参照だった

もう1つは、Canvasの描画そのものが止まっていたことです。CSSではなく、JavaScriptのエラーでした。

JavaScriptでは、let や const で宣言した変数を、宣言の行より前で使うとエラーになります。宣言までのこの区間は TDZ(Temporal Dead Zone)と呼ばれています。E.D.E.N.では、描画の処理がこの区間で変数に触れてしまい、エラーが起きて描画が止まっていました。

描画は毎フレーム繰り返す処理なので、途中で1回エラーが出ると、その先の図形が何も描かれません。画面には枠や文字は出ているのに、中央だけが空いている、という状態になります。エラーの箇所を直して、描画が続くようにしました。

確認したこと

  • ふだん使っているChromeで、通常の画面表示を確認
  • 今回あらためて、ワイド・縦置き・スマホの3つの大きさで表示し、横にはみ出さないことを確認(上の表)
  • コアを1600×1000で3つのモードとも描画できることを確認
  • 縦長の1100×1800でも、コアが切れたり拡大されたりしないことを確認
  • コアが回転していることを、変形の値が変わっていくことで確認
  • 今回の3枚のスクリーンショットは、予定・ToDo・家電などをすべて架空のデータに差し替えた表示用の環境で撮影(時計の表示は隠しています)

わたしが学んだこと

画面の崩れを直すとき、わたしは「見えているもの」を直そうとしていました。ところが実際に詰まったのは、直す途中で見えなくなったもののほうでした。

非表示の指定は、効きすぎても何も言いません。描画のエラーも、画面を見ているだけでは「真ん中が空いている」としか分かりません。レイアウトを変えたら、消していないはずのものが残っているかを、大きさごとに確かめる。今回はその確認を3つの画面サイズで行いました。

このシリーズの続き

E.D.E.N.を作る途中で何を決めて、何をやめたかは、noteのマガジンにまとめています。

→ noteマガジン「E.D.E.N. 開発記」

コメント

タイトルとURLをコピーしました