開発eurekapu-nuxt4

取引SVGの弧軌道アニメーション試作とクイズ正解時の飛びピルアニメーション拡充

テストHTMLを開いて弧軌道の動きを確認した瞬間、「最高ですね、これを求めていました」と書いた。午前中はその気持ちのままSVGアニメーションの試作を一気に進め、午後はクイズ正解時にBS/PLへ仕訳ピルが飛ぶシーケンスの実装とCSパネル追加まで走り切った。

午前:取引SVGアニメーション試作(09:34〜)

発端:旧プロジェクトのSVGをどう活かすか

旧プロジェクトに TransactionNo01Svg.vue という取引イメージSVGがあった。商品仕入れなら「リンゴが移動してお金が逆向きに流れる」を図示するやつで、静止画のまま使っていた。これを弧軌道で動かしたらどうなるか試したくて、まずテストHTMLを作って動きを確認した。

Illustratorでbefore/after SVGの座標を調整し、その座標値をClaude Codeに渡してアニメーションを実装する流れで進めた。株式券とその関連テキスト群をグループ化して、一塊として弧軌道を描く動きを付ける。グループが弧を描いて画面を横断すると、取引のお金と物の流れが視覚的に伝わる。

落とし穴:SVGファイルが存在しなかった

ここで詰まった。旧プロジェクトの TransactionNo01Svg.vue を確認したら、インラインSVGがVueコンポーネント内に手書きで埋め込まれていて、.svg ファイル単体が存在しない。SVGのパスデータをVue SFC内に直接書いている状態だった。

調査すると、cockpit-svgs ディレクトリ内に22個のVueコンポーネントが同じ形式で存在していた。全部コピーして新プロジェクト側に取り込む形で解決した。

Composable化と6パターン分類

素朴なアニメーションをそのまま増やすとコードが爆発するので、useJournalPushAnimation というComposableに切り出した。取引SVGが描く軌道パターンを分析すると6種類に分類できる:

パターン説明
A右方向・通常弧
B右方向・深い弧
C右方向・逆弧
D左方向・通常弧
E左方向・深い弧
F左方向・逆弧

この分類を PATTERN-ANALYSIS.md にまとめ、試作ページでパターンAとパターンD(右/左の代表パターン)を動作確認した。

Illustrator作業なし方針に転換

座標調整をIllustratorで都度やるのは手間が多い。途中で「座標は全部Claude Codeが把握して実装する」方針に切り替えた。SVGのviewBox値と各要素の x/y を静的解析すればIllustratorを起動しなくても座標計算できる。

no07(商品仕入)のSVGではリンゴグループのx座標が中心からずれていたので、+43シフトして中心x座標を揃えた。Illustratorを使わずにエディタ上で数値を調整して確認するサイクルで収まった。

// useJournalPushAnimation の使い方
const { triggerAnimation } = useJournalPushAnimation({
  svgRef,
  pattern: 'A',        // 右方向・通常弧
  duration: 1200,
  onComplete: () => { /* 着弾後の処理 */ },
})

セッション終わりにCodexで3ラウンドレビューを回して4件の指摘を解消し、引き継ぎドキュメントを作成した。

午後:クイズ正解時アニメーション拡充(10:24〜)

quiz/practiceページへの飛びピル追加

quiz/practice ページには正解・不正解の判定があるが、正解したときの演出がなかった。JournalExample.vue にすでに実装済みの flyJournalLine(仕訳ピルを飛ばす関数)と interpolateCount(カウントアップ)を、クイズ側でも使えるようにComposableを切り出した。

BS/PLの各行に data-acct 属性を付与し、仕訳ピルが着弾した先でカウントアップする機構を追加した。「解答&解説」ボタンを押したときは飛ばさず、正解判定が出たときだけ飛ぶ条件分岐を入れた。

アニメーションシーケンスの設計

飛びピルのシーケンスを4段階で設計した:

0〜1s   : ふわふわ浮かび上がる(opacity 0→1、微振動)
1〜2.5s : BS/PLの対象行へ向けてゆっくり飛行
2.5s    : 着弾(弾けるエフェクト)
2.5s〜  : カウントアップ開始

最初に試したシーケンスはふわふわと飛行が重なってぎこちなかった。タイミングを分離して直列に流れるよう修正したら、「仕訳→財務諸表へ反映」の流れが視覚的に読み取れる動きになった。

新規科目のfallback

クイズに登場する科目がBS/PLにまだ表示されていない場合(初回正解で科目行が生成される前)、着弾先のDOM要素が存在しない。この場合はセクションヘッダー(「流動資産」「固定負債」等)へ飛ばすfallbackを入れた。

// 着弾先を取得。なければセクションヘッダーへフォールバック
const targetEl =
  document.querySelector(`[data-acct="${acctCode}"]`) ??
  document.querySelector(`[data-section="${section}"]`)

CSパネルの追加

クイズに現金収支(キャッシュフロー計算書)パネルを追加した。直接法と間接法の両方に対応し、切り替え状態を localStorage で保存する。レイアウトは「CS|BS|PL」の3カラムで横並び。

追加後にCodexレビューを回して3件の指摘を修正。さらに /simplify レビューで4件の修正を行った:

  • watch に不要なガードが入っていたので削除(watchEffect で素直に書き直し)
  • leaky abstraction:内部実装が外に漏れていた箇所を整理
  • 累積/単体モード両方でアニメーションのタイミングがずれるバグを修正

最終的に 412b279 でコミットし、未了事項を quiz-cs-session-pending.md にまとめて次セッションに引き継いだ。

試行錯誤まとめ

  • インラインSVG問題: .svg ファイルと思っていたものがVueコンポーネント内に手書き埋め込みだった。22個のVueコンポーネントを洗い出してコピーすることで解決
  • 座標調整のIllustrator依存: 途中で「全座標をClaude Codeが把握して実装」に方針転換した。no07のリンゴグループ+43シフトのような微調整もエディタ上の数値変更で対応できた
  • アニメーションシーケンス設計: ふわふわ→飛行→着弾→カウントアップの4段階を最初から直列設計にしたら、後からタイミング調整が楽だった

明日やること

  • パターンB・C・E・Fの残り4パターンを試作ページで動作確認
  • no07以外の商品SVG(no08〜no22)の座標調整と弧軌道対応
  • quiz-cs-session-pending.md の未了事項を処理(CSカラムのレスポンシブ対応ほか)