[{"data":1,"prerenderedAt":271},["ShallowReactive",2],{"content-/piano-roll-web-app":3,"related-/piano-roll-web-app":222,"all-pages-for-dir":269,"og-image-/piano-roll-web-app":270},{"id":4,"title":5,"body":6,"category":203,"description":204,"extension":205,"meta":206,"navigation":207,"path":208,"project_name":209,"published":210,"publishedAt":211,"seo":212,"stem":213,"tags":214,"todo":220,"unpublished":210,"updatedAt":220,"__hash__":221},"pages/2026-06/2026-06-11/piano-roll-web-app.md","スクショ1枚からSynthesia風ピアノロールWebアプリを作ってもらった日——88鍵Canvas＋Web Audio合成＋運指表示",{"type":7,"value":8,"toc":193},"minimark",[9,14,18,21,25,32,54,70,74,77,80,92,95,99,102,113,116,119,126,129,133,140,143,146,149,152,160,163,166,176,179],[10,11,13],"h1",{"id":12},"スクショ1枚からsynthesia風ピアノロールwebアプリを作ってもらった日","スクショ1枚からSynthesia風ピアノロールWebアプリを作ってもらった日",[15,16,17],"p",{},"きっかけは雑な依頼だった。YouTubeでよく見る、暗い背景に音符バーが降ってきて鍵盤に届くと光るあの動画のスクリーンショットを1枚貼り付けて、「ピアノアプリってちょっと作ってもらいたいんですけど、できますかね」とだけ聞いた。",[15,19,20],{},"返ってきた答えは「できますよ」。画像を見ただけで「いわゆるSynthesia風のピアノビジュアライザーですね。Web Audio APIで音を合成すれば外部音源なしで作れます」と構成まで言い当ててきた。仕様書はゼロ。画像1枚と一言だけでプロジェクトが始まった。",[22,23,24],"h2",{"id":24},"できあがったもの",[15,26,27,31],{},[28,29,30],"a",{"href":30},"/piano-roll"," として公開済み。",[33,34,35,39,42,45,48,51],"ul",{},[36,37,38],"li",{},"音符バーが画面上部から降ってきて、鍵盤の上端に届いた瞬間に音が鳴り、鍵盤が光る",[36,40,41],{},"88鍵すべてをCanvasで描画。青が右手、金色が左手",[36,43,44],{},"音はWeb Audio APIでリアルタイム合成。音源ファイルは1つも置いていない",[36,46,47],{},"バーに運指番号（1=親指〜5=小指）を表示できるトグル付き",[36,49,50],{},"内蔵曲は「エリーゼのために（主部・約1分）」「カノン」「きらきら星」の3曲",[36,52,53],{},"テンポ（50〜150%）・音量・シークバーあり",[15,55,56,57,61,62,65,66,69],{},"実装は3ファイル構成にしてもらった。鍵盤レイアウト計算や時間変換は純粋関数として ",[58,59,60],"code",{},"app/utils/pianoRoll.ts"," に切り出し、曲データは ",[58,63,64],{},"app/data/piano-roll/songs.ts","、Canvas描画とWeb Audioの副作用は ",[58,67,68],{},"app/pages/piano-roll.vue"," に集約。この分離のおかげで、まず31本のユニットテストが一発で通った。",[22,71,73],{"id":72},"試行錯誤1-再生時計がほぼ止まっていた","試行錯誤1: 再生時計がほぼ止まっていた",[15,75,76],{},"ブラウザでの動作確認に入ったところで、最初のつまずきが出た。再生ボタンを押しても、再生位置がほとんど進まない。",[15,78,79],{},"調べてもらった経過がログに残っている。",[81,82,83,86,89],"ol",{},[36,84,85],{},"「時間の進み方が想定より速い可能性があります。正確に計測します」",[36,87,88],{},"「再生位置がほぼ進んでいません。AudioContextの状態を直接確認します」",[36,90,91],{},"「新しいAudioContextは正常に動くのに、ページ側の時計がほぼ止まっています。もう一度詳しく観察します」",[15,93,94],{},"新しく作ったAudioContextは正常に時を刻むのに、ページが持っている時計だけ止まっている——という切り分けを、ブラウザのコンソールを直接叩いて進めてくれた。私がやったのは画面を眺めていることだけで、計測も切り分けも全部任せた。",[22,96,98],{"id":97},"試行錯誤2-devサーバーが古いコードを配信し続ける","試行錯誤2: devサーバーが古いコードを配信し続ける",[15,100,101],{},"運指番号の描画とトグルを追加してもらった後、今度は「追加したはずの要素が画面に見つからない」問題が出た。これも切り分けの過程が面白かった。",[81,103,104,107,110],{},[36,105,106],{},"「devサーバーが古いコードを配信しています。サーバー側の状態を確認します」",[36,108,109],{},"「Viteは新コードを配信しています。比較のため他ページのSSR出力を確認します」",[36,111,112],{},"「SSRボディは描画されていました。新要素が含まれるか正確に確認します」",[15,114,115],{},"コードが悪いのか、ビルドが悪いのか、配信が悪いのかを一段ずつ潰していき、最終的にはdevサーバーの再起動で新バージョン（曲長0:59・指番号トグルあり）が反映された。待ち時間には並行してブログ記事の執筆まで進めていた。",[22,117,118],{"id":118},"公開前提に切り替える",[15,120,121,122,125],{},"最初はdev環境限定ページとして作ってもらっていたが、できあがりを見て「これ公開前提でよくて、ピアノのコンテンツも公開前提でいいですよ」と伝えた。devゲート・noindex・「開発環境のみ」表記・記事の ",[58,123,124],{},"unpublished"," フラグを一通り外してもらう。",[15,127,128],{},"ここでも一筋縄ではいかなかった。設定を外したはずなのにnoindexが残り続ける。サーバーを再起動しても消えない。「キャッシュではなく別の仕組みが付けている可能性があります」と他ページとの比較確認に進み、最終的に公開化は完了した。",[22,130,132],{"id":131},"不足14件は全部直しましょう","「不足14件は全部直しましょう」",[15,134,135,136,139],{},"公開化の検証でテストを回したところ、失敗が出た。ただし中身を確認すると、失敗は全部 ",[58,137,138],{},"jukuwaza-math"," という私たちが今回まったく触っていないページのOGメタタグ不足。今回の変更とは無関係の、もともと存在していた不備だった。",[15,141,142],{},"放置してもピアノロールの公開には影響しない。でもせっかく見つかったので「不足14件は全部直しましょう」と指示した。テストの要求仕様と対象ページの現状を確認したうえで14ページにOGメタタグを追加してもらい、OGテストは全151件パス。全テストスイートも104ファイル・16,801件すべてグリーンになった。",[15,144,145],{},"ついでの一言で、関係ないページの積年の不備まで片付いた。",[22,147,148],{"id":148},"実装解説記事も同じセッションで",[15,150,151],{},"devサーバーの再起動を待つ間に、実装の詳細をまとめた解説記事も書いてもらった。",[33,153,154],{},[36,155,156],{},[28,157,159],{"href":158},"/piano-roll-implementation","Synthesia風「降ってくる音符」のピアノアプリをWeb Audio + Canvasで作った——実装の詳細メモ",[15,161,162],{},"曲データの持ち方（パブリックドメイン曲の簡略版、著作権保護中の曲はコード進行のみ）、88鍵レイアウトの計算、落下バーの座標系、Web Audioによるピアノ音合成、運指番号、OMRやWeb MIDI対応の展望までカバーしている。",[15,164,165],{},"最後に「コミットしといてください」とだけ伝えると、ピアノ関連の作業一式を3コミットに分割して入れてくれた。",[167,168,173],"pre",{"className":169,"code":171,"language":172},[170],"language-text","feat: Synthesia風ピアノロール /piano-roll を追加（88鍵Canvas＋Web Audio合成・運指表示）\ndocs: ピアノロールの実装解説記事を追加（曲データ設計・座標系・音合成・OMR/Web MIDI展望）\n","text",[58,174,171],{"__ignoreMap":175},"",[22,177,178],{"id":178},"ふりかえり",[33,180,181,184,187,190],{},[36,182,183],{},"入力は画像1枚と「作ってもらいたいんですけど」の一言。そこから機能の特定、技術選定、実装、テスト、ブラウザ検証、記事執筆、コミット分割まで流れた",[36,185,186],{},"試行錯誤は2回（止まる再生時計、古いコードを配信するdevサーバー）。どちらも「計測する→切り分ける→比較する」の手順をログに残しながら進めてくれたので、私は画面の違和感を伝える係に徹した",[36,188,189],{},"テストの失敗を「自分の変更と無関係」と確認したうえで、それでも直す判断は人間側でできる。「不足14件は全部直しましょう」の一言で16,801件グリーンまで持っていけたのは気持ちがよかった",[36,191,192],{},"公開/非公開の判断は早めに伝えるべきだった。後からdevゲートを外す作業でnoindexの謎調査が1往復増えた",{"title":175,"searchDepth":194,"depth":194,"links":195},2,[196,197,198,199,200,201,202],{"id":24,"depth":194,"text":24},{"id":72,"depth":194,"text":73},{"id":97,"depth":194,"text":98},{"id":118,"depth":194,"text":118},{"id":131,"depth":194,"text":132},{"id":148,"depth":194,"text":148},{"id":178,"depth":194,"text":178},"dev","「ピアノアプリ作ってもらいたいんですけど」と画像1枚を見せたところから、Synthesia風ピアノロール /piano-roll が完成するまでの記録。再生時計が止まる謎、devサーバーの古いコード配信、公開化で見つかったOGメタタグ不足14件の一括修正まで。","md",{},true,"/piano-roll-web-app","mdx-playground",false,"2026-06-11T00:00:00.000Z",{"title":5,"description":204},"2026-06/2026-06-11/piano-roll-web-app",[215,216,217,218,219],"ピアノロール","Web Audio","Canvas","Claude Code","Nuxt",null,"biEShN3newM-PUU3GEDkX_9irulXAWs1EQe2doK_Kxk",[223,229,237,246,259],{"title":159,"description":224,"path":158,"tags":225,"publishedAt":211,"updatedAt":220},"音符バーが上から降ってきて鍵盤に届くと音が鳴るピアノビジュアライザー /piano-roll の実装記録。曲データの持ち方、88鍵レイアウト計算、落下バーの座標系、Web Audioによるピアノ音合成、運指番号表示、楽譜データの入手方法やMIDIキーボード対応の展望まで。",[216,217,226,227,228,219],"Vue","ピアノ","音楽",{"title":230,"description":231,"path":232,"tags":233,"publishedAt":211,"updatedAt":220},"簿記学習ノートの演習を自作問題集ベースに再設計し、クラウド会計風の帳簿アプリを実装した日","自動生成した70問を捨てて検証済みの自作仕訳問題集に演習を置き換えた記録。長大ページの分割、学習方法ページの不整合解消、紙の帳簿前提の出題への違和感から仕訳帳・総勘定元帳・補助元帳をテーブルで再現する帳簿アプリも新規実装した。","/bookkeeping-notes-practice-redesign",[234,235,219,218,236],"簿記","教材設計","開発日記",{"title":238,"description":239,"path":240,"tags":241,"publishedAt":245,"updatedAt":220},"Google Search Console 分析で見つけた機会キーワードに即日対応した記録 ― 解説記事の量産と SEO 修正を1日で消化する","GSC の過去28日データを Claude Web に分析させたら CTR 2.3%・平均掲載順位8.4 という「表示はされるが選ばれない」状態が判明。機会キーワードへの解説記事量産と SEO 修正を同日に実行した作業ログ。","/gsc-opportunity-keywords-execution",[242,243,218,219,244],"SEO","Google Search Console","ブログ運営","2026-06-09T00:00:00.000Z",{"title":247,"description":248,"path":249,"tags":250,"publishedAt":258,"updatedAt":220},"2026年4月28日の開発日記 - feature-slidesスキル新設、書籍OCR1181ページ、Amazon書棚UIまで1日で組み上げた","別リポジトリ eurekapu-nuxt4 でCFWS v2の構造解説スライドを reveal.js で組む過程から汎用スキル feature-slides まで一気に成立させ、Excel忠実再現グリッドと範囲外枠ハイライトまで詰めた。並行して book-knowledge-base 側で yomitoku を5冊・1181ページに通して Turso DB に1057チャンク登録、Amazon の星評価・メタデータを 935件中 841件取得して Nuxt の書棚UI で公開した。SVG図解の作業も svg-diagram スキル v2 として書籍画像→SVG変換ワークフローを追記。","/2026-04-28-diary",[251,218,252,253,254,255,256,219,257],"日記","スキル","reveal.js","yomitoku","Turso","Amazon","SVG","2026-04-28T00:00:00.000Z",{"title":260,"description":261,"path":262,"tags":263,"publishedAt":268,"updatedAt":220},"ステレオサウンドテストページをVue 3/Nuxtで実装 - Web Audio APIによる左右チャンネル出し分け","ReactのJSXで作ったステレオテストページをVue 3 + Nuxtに移植。StereoWaveCanvasコンポーネントの新規作成、Web Audio APIによるL/Rチャンネル分離、Chrome DevTools MCPでの動作確認まで。","/stereo-wave-canvas-vue-2026-02-18",[264,219,265,217,266,267],"Vue3","Web Audio API","ステレオ","コンポーネント移植","2026-02-18T00:00:00.000Z",[],"https://log.eurekapu.com/og/blog/piano-roll-web-app.png?v=2026-06-11T00%3A00%3A00.000Z&title=%E3%82%B9%E3%82%AF%E3%82%B7%E3%83%A71%E6%9E%9A%E3%81%8B%E3%82%89Synthesia%E9%A2%A8%E3%83%94%E3%82%A2%E3%83%8E%E3%83%AD%E3%83%BC%E3%83%ABWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%82%82%E3%82%89%E3%81%A3%E3%81%9F%E6%97%A5%E2%80%94%E2%80%9488%E9%8D%B5Canvas%EF%BC%8BWeb%20Audio%E5%90%88%E6%88%90%EF%BC%8B%E9%81%8B%E6%8C%87%E8%A1%A8%E7%A4%BA&author=Kei%20Komatsu&sig=fb51aa8631c6e649",1781333882237]