はじめに
ブラウザを開いたときに表示される「新規タブ」って殺風景ですよね。
作ったものと技術スタック
結論 / できたこと
SAO(ソードアート・オンライン)の無機質でスタイリッシュなUIと、サマーウォーズのOZの浮遊感をイメージした、Canvasアニメーション付きの個人ページをつくりました。
github pagesで公開しています。
技術スタック
- HTML / CSS / JS(フレームワークなし)
- Canvas 2D API
-
fetch+ JSON / JSONL - GitHub Pages / GitHub Codespace
- Claude Code
主な機能
- メインパネル:登録したアイデンティティをタイプライター風に表示し、カタカナのグリッチエフェクトで次の言葉へサイクル表示します。
- Canvasアニメーション背景:SAO風の六角形、OZ風の円やダイヤ、星座線などをランダムに浮遊させています。
- ELEMENTタグ:名前や趣味、思い入れのある作品をタグとして並べ、クリックするとモーダルが開き、詳細な説明や検索ボタンを表示します。
-
データ外部化:データは
profile.jsonとlinks.jsonlに分離し、コード本体を触らなくても更新できるようにしました。
ポイント
実装は、ClaudeのArtifactでプロトタイプを作り、その後GitHub Pagesへ移行して細部を詰めていく流れで進めました。
グリッチプールの自動切り替え
アイデンティティのテキストが切り替わる際、文字種の判定を行ってグリッチ(文字化け)エフェクトの演出を変えています。
function glitchPool(str) {
return isJapanese(str)
? 'ヲアイウエオカキクケコサシスセソタチナニハヒフヘホ▓░◈'
: '▓▒░█▄▀■□◈◊#@$%!?';
}
日本語が含まれる場合はカタカナのノイズを、ラテン文字の場合はブロック要素のノイズを返します。やっていることはシンプルですが、これだけで画面全体の世界観に統一感が出ました。
CSSカスタムプロパティでのテーマカラー切り替え
タグをクリックしてモーダルを開く際、項目ごとに設定されたアクセントカラーを適用しています。
panel.style.setProperty('--mc', item.color);
モーダルの親要素に --mc(メインカラー)を設定するだけで、上部バー、コーナーの装飾、ボタン、フォーカスリングなどの色が一括で切り替わります。CSSの変数継承をうまく活用できたので、コードがすっきりしました。
文字数に適応するアニメーション速度
タイプライター風のエフェクトで、文字数にかかわらず総アニメーション時間を約500msに揃える計算を入れました。
const ms = Math.max(10, Math.floor(500 / desc.length));
typeInEl(descEl, desc, ms, null);
短い文章はゆっくり、長い文章は速く表示されます。最低速度を10msでキャップすることで、長文でも不自然にならないように調整しています。地味ですが、表示のテンポが良くなり助かりました。
GitHub Codespaceによる環境に依存しない更新
データとロジックを分離したことで、profile.json を書き換えるだけでコンテンツの更新が可能になりました。
GitHub Codespaceを使えば、ブラウザ上でJSONを編集し、コミットするだけでGitHub Pagesへデプロイされます。ローカルに開発環境を用意しなくても、思い立ったときにすぐ変更できるのは非常に便利です。
ハマったところ / 注意点
開発中にいくつか詰まった点がありました。
| 問題 | 原因 | 解決策 |
|---|---|---|
fetch() が動かない |
ローカルの file:// ではCORSブロックが発生する |
ターミナルで python3 -m http.server 8080 を実行してローカルサーバーを立てた |
| CSSの変更が反映されない | ブラウザのキャッシュが古いファイルを読み込んでいる | 読み込みURLに ?v=1.0 などのクエリを追加してキャッシュバスティングを行った |
| アニメーションが二重起動する | 前のモーダルのタイマーが残ったまま別のモーダルを開いた |
clearModalTimers() を作成し、開く前に setTimeout を全キャンセルした |
JSON内の \n が改行されない |
textContent はブラウザ上で改行文字を無視する |
description要素のCSSに white-space: pre-line を付与した |
| 長い見出しが不自然に折り返す | 固定フォントサイズと等幅フォントの組み合わせ |
data-len 属性で文字数に応じたフォントサイズ縮小と word-break: auto-phrase を設定 |
おわりに
デザインの方向性(SAOやOZの疾走感・未来感)については、まだ完全に表現しきれていないと感じています。AIに「スタイリッシュに」と伝えるだけでは限界があり、どのシーンのどのフレームが良いのか、具体的なリファレンスを言語化して指示する必要があることがわかりました。
とりあえずはアニメを見返しつつ、このあたりの表現を少しずつ調整していきたいです。
