[{"data":1,"prerenderedAt":563},["ShallowReactive",2],{"content-/transaction-svg-animation-quiz":3,"all-pages-for-dir":561,"og-image-/transaction-svg-animation-quiz":562},{"id":4,"title":5,"body":6,"category":544,"description":545,"extension":546,"meta":547,"navigation":509,"ogImage":548,"path":549,"project_name":550,"published":551,"publishedAt":552,"seo":553,"stem":554,"tags":555,"todo":548,"unpublished":551,"updatedAt":548,"__hash__":560},"pages/2026-05/2026-05-05/transaction-svg-animation-quiz.md","取引SVGの弧軌道アニメーション試作とクイズ正解時の飛びピルアニメーション拡充",{"type":7,"value":8,"toc":528},"minimark",[9,13,17,22,27,35,38,42,52,55,59,66,134,141,145,156,159,274,277,281,285,300,307,310,313,321,324,327,330,420,424,431,438,458,469,472,495,498,524],[10,11,5],"h1",{"id":12},"取引svgの弧軌道アニメーション試作とクイズ正解時の飛びピルアニメーション拡充",[14,15,16],"p",{},"テストHTMLを開いて弧軌道の動きを確認した瞬間、「最高ですね、これを求めていました」と書いた。午前中はその気持ちのままSVGアニメーションの試作を一気に進め、午後はクイズ正解時にBS/PLへ仕訳ピルが飛ぶシーケンスの実装とCSパネル追加まで走り切った。",[18,19,21],"h2",{"id":20},"午前取引svgアニメーション試作0934","午前：取引SVGアニメーション試作（09:34〜）",[23,24,26],"h3",{"id":25},"発端旧プロジェクトのsvgをどう活かすか","発端：旧プロジェクトのSVGをどう活かすか",[14,28,29,30,34],{},"旧プロジェクトに ",[31,32,33],"code",{},"TransactionNo01Svg.vue"," という取引イメージSVGがあった。商品仕入れなら「リンゴが移動してお金が逆向きに流れる」を図示するやつで、静止画のまま使っていた。これを弧軌道で動かしたらどうなるか試したくて、まずテストHTMLを作って動きを確認した。",[14,36,37],{},"Illustratorでbefore/after SVGの座標を調整し、その座標値をClaude Codeに渡してアニメーションを実装する流れで進めた。株式券とその関連テキスト群をグループ化して、一塊として弧軌道を描く動きを付ける。グループが弧を描いて画面を横断すると、取引のお金と物の流れが視覚的に伝わる。",[23,39,41],{"id":40},"落とし穴svgファイルが存在しなかった","落とし穴：SVGファイルが存在しなかった",[14,43,44,45,47,48,51],{},"ここで詰まった。旧プロジェクトの ",[31,46,33],{}," を確認したら、インラインSVGがVueコンポーネント内に手書きで埋め込まれていて、",[31,49,50],{},".svg"," ファイル単体が存在しない。SVGのパスデータをVue SFC内に直接書いている状態だった。",[14,53,54],{},"調査すると、cockpit-svgs ディレクトリ内に22個のVueコンポーネントが同じ形式で存在していた。全部コピーして新プロジェクト側に取り込む形で解決した。",[23,56,58],{"id":57},"composable化と6パターン分類","Composable化と6パターン分類",[14,60,61,62,65],{},"素朴なアニメーションをそのまま増やすとコードが爆発するので、",[31,63,64],{},"useJournalPushAnimation"," というComposableに切り出した。取引SVGが描く軌道パターンを分析すると6種類に分類できる：",[67,68,69,82],"table",{},[70,71,72],"thead",{},[73,74,75,79],"tr",{},[76,77,78],"th",{},"パターン",[76,80,81],{},"説明",[83,84,85,94,102,110,118,126],"tbody",{},[73,86,87,91],{},[88,89,90],"td",{},"A",[88,92,93],{},"右方向・通常弧",[73,95,96,99],{},[88,97,98],{},"B",[88,100,101],{},"右方向・深い弧",[73,103,104,107],{},[88,105,106],{},"C",[88,108,109],{},"右方向・逆弧",[73,111,112,115],{},[88,113,114],{},"D",[88,116,117],{},"左方向・通常弧",[73,119,120,123],{},[88,121,122],{},"E",[88,124,125],{},"左方向・深い弧",[73,127,128,131],{},[88,129,130],{},"F",[88,132,133],{},"左方向・逆弧",[14,135,136,137,140],{},"この分類を ",[31,138,139],{},"PATTERN-ANALYSIS.md"," にまとめ、試作ページでパターンAとパターンD（右/左の代表パターン）を動作確認した。",[23,142,144],{"id":143},"illustrator作業なし方針に転換","Illustrator作業なし方針に転換",[14,146,147,148,151,152,155],{},"座標調整をIllustratorで都度やるのは手間が多い。途中で「座標は全部Claude Codeが把握して実装する」方針に切り替えた。SVGのviewBox値と各要素の ",[31,149,150],{},"x","/",[31,153,154],{},"y"," を静的解析すればIllustratorを起動しなくても座標計算できる。",[14,157,158],{},"no07（商品仕入）のSVGではリンゴグループのx座標が中心からずれていたので、+43シフトして中心x座標を揃えた。Illustratorを使わずにエディタ上で数値を調整して確認するサイクルで収まった。",[160,161,166],"pre",{"className":162,"code":163,"language":164,"meta":165,"style":165},"language-typescript shiki shiki-themes vitesse-light vitesse-light","// useJournalPushAnimation の使い方\nconst { triggerAnimation } = useJournalPushAnimation({\n  svgRef,\n  pattern: 'A',        // 右方向・通常弧\n  duration: 1200,\n  onComplete: () => { /* 着弾後の処理 */ },\n})\n","typescript","",[31,167,168,177,205,214,239,253,268],{"__ignoreMap":165},[169,170,173],"span",{"class":171,"line":172},"line",1,[169,174,176],{"class":175},"sxvE3","// useJournalPushAnimation の使い方\n",[169,178,180,184,188,192,195,198,202],{"class":171,"line":179},2,[169,181,183],{"class":182},"stQ0i","const ",[169,185,187],{"class":186},"shFtX","{",[169,189,191],{"class":190},"s4oTP"," triggerAnimation",[169,193,194],{"class":186}," }",[169,196,197],{"class":186}," =",[169,199,201],{"class":200},"senZ8"," useJournalPushAnimation",[169,203,204],{"class":186},"({\n",[169,206,208,211],{"class":171,"line":207},3,[169,209,210],{"class":190},"  svgRef",[169,212,213],{"class":186},",\n",[169,215,217,221,224,228,231,233,236],{"class":171,"line":216},4,[169,218,220],{"class":219},"sz8Xr","  pattern",[169,222,223],{"class":186},": ",[169,225,227],{"class":226},"sMJiu","'",[169,229,90],{"class":230},"sdGka",[169,232,227],{"class":226},[169,234,235],{"class":186},",        ",[169,237,238],{"class":175},"// 右方向・通常弧\n",[169,240,242,245,247,251],{"class":171,"line":241},5,[169,243,244],{"class":219},"  duration",[169,246,223],{"class":186},[169,248,250],{"class":249},"sM54T","1200",[169,252,213],{"class":186},[169,254,256,259,262,265],{"class":171,"line":255},6,[169,257,258],{"class":200},"  onComplete",[169,260,261],{"class":186},": () => { ",[169,263,264],{"class":175},"/* 着弾後の処理 */",[169,266,267],{"class":186}," },\n",[169,269,271],{"class":171,"line":270},7,[169,272,273],{"class":186},"})\n",[14,275,276],{},"セッション終わりにCodexで3ラウンドレビューを回して4件の指摘を解消し、引き継ぎドキュメントを作成した。",[18,278,280],{"id":279},"午後クイズ正解時アニメーション拡充1024","午後：クイズ正解時アニメーション拡充（10:24〜）",[23,282,284],{"id":283},"quizpracticeページへの飛びピル追加","quiz/practiceページへの飛びピル追加",[14,286,287,288,291,292,295,296,299],{},"quiz/practice ページには正解・不正解の判定があるが、正解したときの演出がなかった。",[31,289,290],{},"JournalExample.vue"," にすでに実装済みの ",[31,293,294],{},"flyJournalLine","（仕訳ピルを飛ばす関数）と ",[31,297,298],{},"interpolateCount","（カウントアップ）を、クイズ側でも使えるようにComposableを切り出した。",[14,301,302,303,306],{},"BS/PLの各行に ",[31,304,305],{},"data-acct"," 属性を付与し、仕訳ピルが着弾した先でカウントアップする機構を追加した。「解答＆解説」ボタンを押したときは飛ばさず、正解判定が出たときだけ飛ぶ条件分岐を入れた。",[23,308,309],{"id":309},"アニメーションシーケンスの設計",[14,311,312],{},"飛びピルのシーケンスを4段階で設計した：",[160,314,319],{"className":315,"code":317,"language":318},[316],"language-text","0〜1s   : ふわふわ浮かび上がる（opacity 0→1、微振動）\n1〜2.5s : BS/PLの対象行へ向けてゆっくり飛行\n2.5s    : 着弾（弾けるエフェクト）\n2.5s〜  : カウントアップ開始\n","text",[31,320,317],{"__ignoreMap":165},[14,322,323],{},"最初に試したシーケンスはふわふわと飛行が重なってぎこちなかった。タイミングを分離して直列に流れるよう修正したら、「仕訳→財務諸表へ反映」の流れが視覚的に読み取れる動きになった。",[23,325,326],{"id":326},"新規科目のfallback",[14,328,329],{},"クイズに登場する科目がBS/PLにまだ表示されていない場合（初回正解で科目行が生成される前）、着弾先のDOM要素が存在しない。この場合はセクションヘッダー（「流動資産」「固定負債」等）へ飛ばすfallbackを入れた。",[160,331,333],{"className":162,"code":332,"language":164,"meta":165,"style":165},"// 着弾先を取得。なければセクションヘッダーへフォールバック\nconst targetEl =\n  document.querySelector(`[data-acct=\"${acctCode}\"]`) ??\n  document.querySelector(`[data-section=\"${section}\"]`)\n",[31,334,335,340,350,391],{"__ignoreMap":165},[169,336,337],{"class":171,"line":172},[169,338,339],{"class":175},"// 着弾先を取得。なければセクションヘッダーへフォールバック\n",[169,341,342,344,347],{"class":171,"line":179},[169,343,183],{"class":182},[169,345,346],{"class":190},"targetEl",[169,348,349],{"class":186}," =\n",[169,351,352,355,358,361,364,367,370,374,377,380,383,385,388],{"class":171,"line":207},[169,353,354],{"class":190},"  document",[169,356,357],{"class":186},".",[169,359,360],{"class":200},"querySelector",[169,362,363],{"class":186},"(",[169,365,366],{"class":226},"`",[169,368,369],{"class":230},"[data-acct=\"",[169,371,373],{"class":372},"sHkkW","${",[169,375,376],{"class":230},"acctCode",[169,378,379],{"class":372},"}",[169,381,382],{"class":230},"\"]",[169,384,366],{"class":226},[169,386,387],{"class":186},")",[169,389,390],{"class":182}," ??\n",[169,392,393,395,397,399,401,403,406,408,411,413,415,417],{"class":171,"line":216},[169,394,354],{"class":190},[169,396,357],{"class":186},[169,398,360],{"class":200},[169,400,363],{"class":186},[169,402,366],{"class":226},[169,404,405],{"class":230},"[data-section=\"",[169,407,373],{"class":372},[169,409,410],{"class":230},"section",[169,412,379],{"class":372},[169,414,382],{"class":230},[169,416,366],{"class":226},[169,418,419],{"class":186},")\n",[23,421,423],{"id":422},"csパネルの追加","CSパネルの追加",[14,425,426,427,430],{},"クイズに現金収支（キャッシュフロー計算書）パネルを追加した。直接法と間接法の両方に対応し、切り替え状態を ",[31,428,429],{},"localStorage"," で保存する。レイアウトは「CS｜BS｜PL」の3カラムで横並び。",[14,432,433,434,437],{},"追加後にCodexレビューを回して3件の指摘を修正。さらに ",[31,435,436],{},"/simplify"," レビューで4件の修正を行った：",[439,440,441,452,455],"ul",{},[442,443,444,447,448,451],"li",{},[31,445,446],{},"watch"," に不要なガードが入っていたので削除（",[31,449,450],{},"watchEffect"," で素直に書き直し）",[442,453,454],{},"leaky abstraction：内部実装が外に漏れていた箇所を整理",[442,456,457],{},"累積/単体モード両方でアニメーションのタイミングがずれるバグを修正",[14,459,460,461,464,465,468],{},"最終的に ",[31,462,463],{},"412b279"," でコミットし、未了事項を ",[31,466,467],{},"quiz-cs-session-pending.md"," にまとめて次セッションに引き継いだ。",[18,470,471],{"id":471},"試行錯誤まとめ",[439,473,474,483,489],{},[442,475,476,223,480,482],{},[477,478,479],"strong",{},"インラインSVG問題",[31,481,50],{}," ファイルと思っていたものがVueコンポーネント内に手書き埋め込みだった。22個のVueコンポーネントを洗い出してコピーすることで解決",[442,484,485,488],{},[477,486,487],{},"座標調整のIllustrator依存",": 途中で「全座標をClaude Codeが把握して実装」に方針転換した。no07のリンゴグループ+43シフトのような微調整もエディタ上の数値変更で対応できた",[442,490,491,494],{},[477,492,493],{},"アニメーションシーケンス設計",": ふわふわ→飛行→着弾→カウントアップの4段階を最初から直列設計にしたら、後からタイミング調整が楽だった",[18,496,497],{"id":497},"明日やること",[439,499,502,512,518],{"className":500},[501],"contains-task-list",[442,503,506,511],{"className":504},[505],"task-list-item",[507,508],"input",{"disabled":509,"type":510},true,"checkbox"," パターンB・C・E・Fの残り4パターンを試作ページで動作確認",[442,513,515,517],{"className":514},[505],[507,516],{"disabled":509,"type":510}," no07以外の商品SVG（no08〜no22）の座標調整と弧軌道対応",[442,519,521,523],{"className":520},[505],[507,522],{"disabled":509,"type":510}," quiz-cs-session-pending.md の未了事項を処理（CSカラムのレスポンシブ対応ほか）",[525,526,527],"style",{},"html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .sM54T, html code.shiki .sM54T{--shiki-default:#2F798A;--shiki-dark:#2F798A}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}",{"title":165,"searchDepth":179,"depth":179,"links":529},[530,536,542,543],{"id":20,"depth":179,"text":21,"children":531},[532,533,534,535],{"id":25,"depth":207,"text":26},{"id":40,"depth":207,"text":41},{"id":57,"depth":207,"text":58},{"id":143,"depth":207,"text":144},{"id":279,"depth":179,"text":280,"children":537},[538,539,540,541],{"id":283,"depth":207,"text":284},{"id":309,"depth":207,"text":309},{"id":326,"depth":207,"text":326},{"id":422,"depth":207,"text":423},{"id":471,"depth":179,"text":471},{"id":497,"depth":179,"text":497},"dev","旧プロジェクトの取引イメージSVGを弧軌道アニメーションに昇華し、クイズ正解時にBS/PLへ仕訳ピルが飛ぶシーケンスを実装。インラインSVG問題の発見からComposable化、CSパネル追加まで一気に進めた開発ログ","md",{},null,"/transaction-svg-animation-quiz","eurekapu-nuxt4",false,"2026-05-05T00:00:00.000Z",{"title":5,"description":545},"2026-05/2026-05-05/transaction-svg-animation-quiz",[556,557,558,559],"SVG","アニメーション","クイズ","Vue","A14GbD4PSajg_b6_WR82Eipn_dSLeSW615fE_b3vsF0",[],"https://log.eurekapu.com/og/blog/transaction-svg-animation-quiz.png?v=2026-05-05T00%3A00%3A00.000Z&title=%E5%8F%96%E5%BC%95SVG%E3%81%AE%E5%BC%A7%E8%BB%8C%E9%81%93%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E8%A9%A6%E4%BD%9C%E3%81%A8%E3%82%AF%E3%82%A4%E3%82%BA%E6%AD%A3%E8%A7%A3%E6%99%82%E3%81%AE%E9%A3%9B%E3%81%B3%E3%83%94%E3%83%AB%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E6%8B%A1%E5%85%85&author=Kei%20Komatsu&sig=d9c9471cf9c70088",1782528833309]