アナレンマ・シミュレーターをダークテーマ&ドラッグ操作に全面刷新し、視点切替シミュレーションを追加した

朝、/blog/analemma-simulator を開いて眺めていたら、どうにも操作する気が起きない画面だった。スライダーを動かすだけの白背景のページ。Claude Code に「これもうちょっとインタラクティブでかっこよくできませんかね」とだけ投げて、刷新作業を始めた。

やったこと

  • アナレンマ・シミュレーターをダークテーマ&ドラッグ操作に全面刷新
  • 「強い傾き」プリセットで8の字が画面外にはみ出すバグを修正
  • /blog/analemma-claude の分かりやすさ改善とバグチェック
  • 北極視点/南極視点を切り替えられる独立シミュレーションページ /blog/orbit-viewpoint を追加
  • SVG座標の丸め漏れによる hydration 警告を解消
  • /commit で機能単位の分割コミット(前半7コミット+後半2コミット)

「かっこよく」を形にする: frontend-design スキルで全面刷新

雑な依頼に対して、frontend-design スキルを適用して作業を進めてもらった。このスキルは「AIっぽい無難なデザイン」を避けて、デザインの方向性をまず決めてから実装するという流れを持っている。

出てきたコンセプトは「プラネタリウム×多重露光写真」。夜空のダークテーマを基調に、太陽の軌跡が多重露光写真のように残像を重ねていく見せ方になった。操作面では、スライダーを廃止して太陽・地球・グラフを直接ドラッグして日付を動かせるようにしてもらった。グラフ上の点を掴んで横に滑らせると、空の上の太陽が8の字をなぞって動く。スライダーを往復していた頃と違って、手応えが画面に直結する。

刷新ついでのバグチェックで、実バグが1件見つかった。「強い傾き」プリセット(地軸の傾きを大きくした場合)で、アナレンマの8の字が SVG の描画領域からはみ出していた。極端なパラメータを入れたときの境界は、デザイン刷新のようなタイミングでないと誰も踏まない。修正まで含めて、ここで前半戦を /commit の分割コミットで7コミットに分けて積んだ。

feat: アナレンマ・シミュレーターをダークテーマ&ドラッグ操作に全面刷新

analemma-claude の分かりやすさ改善とバグチェック

続けて解説ページの /blog/analemma-claude も「もうちょっとわかりやすくしてほしい。バグ入ってないかチェックして」と依頼した。

計算ロジック(analemma-claude.ts)とページ本体を読んでもらい、既存テスト41件が全部パスすることを確認。utils を触ったのでカバレッジも取得。さらにブラウザでプリセットの描画確認とコンソールエラーチェックまで回してもらった。途中、デバッグ用 Chrome が私の実 Chrome に繋がっていて、δ(太陽赤緯)が +19.19° と動いた状態のスクリーンショットが返ってきたのは少し笑った。私が手元でいじった日付がそのまま検証対象になっていた。

結論は「公転の向きは反時計回りで合っています(北極側から見下ろした場合)」。

「言ってることがわかんない」から生まれた視点切替ページ

ここで引っかかった。「北極側から見下ろした場合」と言われても、頭の中に絵が浮かばない。

「ごめん、ちょっと言ってることがわかんないんですけど」と正直に返した。北極側から見たら反時計回り、南極側(反対側)から見たら時計回り。同じ公転を反対側から見れば回転方向が逆に見える──それ自体は理屈では分かる。でも文章で「〜から見下ろした場合」と書かれても、読者は視点をいちいち頭の中で組み立て直すことになる。図を1枚入れる程度では足りない気がした。

そこで方針を変えた。解説に図を足すのではなく、視点そのものを切り替えられる独立したシミュレーションページを作ってもらうことにした。北極視点と南極視点をボタンで切り替えると、同じ公転アニメーションの回転方向が逆転して見える。「逆になることが整合的」だと、説明されるのではなく自分の目で確かめられる。

Claude Code 側は vue-pages スキルと TableOfContents の既存パターンを確認してから、純粋関数のテスト13件を先に通し、ページ本体 /blog/orbit-viewpoint を作成。ブログ一覧とトップページのナビカードへの登録までやってくれた。

完成後の一言が腑に落ちた。「時計を後ろから見るか前から見るかと同じで、公転も同じ運動を公転面のどちら側から見るかだけの違い」。最初からこう言ってくれれば──いや、最初の説明が通じなかったからこそ、このページが生まれたのだった。

feat: 公転の向きと視点ページを追加(北極側=反時計回り・南極側=時計回り)

SVG座標の丸め漏れで hydration 警告

新ページのブラウザ確認で、hydration 警告が出ていた。原因は SVG 座標のバインディングに浮動小数点をそのまま流していたこと。SSR とクライアントで桁数の出方がずれて、サーバーの HTML とクライアントの仮想 DOM が食い違う。

round2 で座標を丸める修正を入れ、ついでに他の SVG 座標バインディングも同様のリスクがあるのでまとめて丸めてもらった。1箇所直して終わりにせず、同じパターンを横展開して潰すのは指示しなくてもやってくれた。ハードリロードで警告が消えたことを確認して、テストとカバレッジも再確認。

分割コミットの小さな罠

最後に /commit でステージングコミット。ここで index.vue別セッションで作業していた zaimu-dd のカードが混ざっていることを検出してくれた。差分全体を確認したうえで、今セッション分だけを2コミットに分けて積んでいる。複数セッションを並行して走らせていると作業ツリーが混ざるので、コミット前に差分の出どころを切り分けてくれるのは助かる。

学び

  • 「かっこよく」という雑な依頼でも、frontend-design スキルがコンセプト(プラネタリウム×多重露光)から決めてくれるので、出てくるものが無難なグラデーションボタンにならない
  • 説明が通じないときは、説明を増やすのではなく、読者が自分で動かして確かめられるシミュレーションに変換するという解決策がある。「視点を切り替えたら回転が逆に見える」は、文章100行より切替ボタン1個のほうが速い
  • SVG 座標に浮動小数点を直接バインドすると SSR/CSR で hydration mismatch を起こす。round2 で丸める。1箇所見つけたら同パターンを横展開して全部潰す
  • 極端なプリセット(強い傾き)は描画領域の境界バグの温床。パラメータの端を踏むテストは刷新時にやる価値がある

明日やること

  • /blog/orbit-viewpoint を実機(スマホ)で開いて、視点切替ボタンのタップ操作とアニメーションの滑らかさを確認する
  • アナレンマ関連3ページ(simulator / claude / orbit-viewpoint)の相互リンクが揃っているか確認する