開発Tips

ストア掲載画像を実機なしで作る Claude Code スキルを自作した

ストア掲載用のスクリーンショットは、リリースのたびに端末サイズ・ライト/ダーク分を撮り直す必要があり、手作業だと地味に重い工程です。「ぽんっ!」(旧称:でいりんぐ)ではこれを Flutter の golden テスト + 静的HTML + Playwright で半自動化し、Claude Code のスキルとして何度でも再現できるようにしました。2 部構成(撮影 → 装飾)で、それぞれの具体をまとめます。

背景(当時の状況)

この仕組みを整えたのは、キャラ刷新(2026-07-10)にあわせてストア画像と SNS 素材を一気に作り直す必要が出たときでした。リリースのたびに端末サイズ違い・ライト/ダーク違いのスクショを撮り直すのは骨が折れるので、「二度と手作業に戻らない」ことを目標に半自動のパイプラインとして組み、Claude Code のスキルに落とし込みました。

Part 1: スクショは golden テストで撮る

ストア画像は結局「特定画面の見た目」です。であれば、golden テスト(ウィジェットのレンダリング結果を PNG に書き出す仕組み)を撮影ハーネスに転用すれば、実機もエミュレータも要りません。

  • 撮影ハーネス(test/screenshot/)で各画面を ライト/ダークでレンダリングして PNG を書き出す。撮影用のフラグは不要で、flutter test test/screenshot/ を回すと生 PNG が dayring_app/{ios,android}/store/ に出ます。
  • 端末は 4 スペック(device_specs.dart): iPhone(1320×2868) / iPad(2064×2752) / Android phone / Android tablet
  • 対象画面は、こどもホーム・おとなホーム・最終進化演出・がんばったねカード・スタンプ選択などの主要画面。全画面を一括で撮る review_all_screens_test.dart もあります(これは HIG 監査にも転用しています)。

「映える状態」をダミーデータで作る

生スクショが映えるかは中身次第です。専用のダミーデータ(screenshot_dummy_data.dart)で、埋まった状態を作り込みます。

  • こども「たろう」、おとな「ぱぱ」、連携こども「たろう/はなこ」、連携おとな「まま」など、家族連携が成立した状態
  • ごほうびシートは 24/25 マス埋まった状態、がんばったねカードにスタンプが並んだ状態。
  • 図鑑は、colorsMask(0x1=ノーマル / 0x2=色違い / 0x3=両方)で色違いも含めて集まった状態。

実機で「映える状態」を手作りするより、ダミーデータで確定した状態を注入するほうが速く、毎回同じ絵が撮れます。

Part 2: 装飾は静的HTML + Playwright + sharp

生スクショに端末フレームやキャッチコピーを乗せる装飾は、store_assets/export.mjsnode export.mjs)で行います。Next.js は使わず、静的な HTML を Playwright(headless Chromium) でレンダリングして locator.screenshot で切り出し、sharp でアルファを除去(RGB 化)してストア規定に合わせます。

  • 入力: Part 1 の生スクショ dayring_app/{ios,android}/store/*.png
  • 出力: store/{ios|android}/{phone|tablet}/{light|dark}/
  • アセットは base64 で HTML に埋め込む(フォント M PLUS Rounded 1c、iPhone モックアップ、アプリアイコン)。外部ホットリンクを避け、レンダリングを自己完結させる。
  • テーマは DESIGN.md の「Warm & Analog」(ライト/ダーク)に揃え、アクセントはライト #F28C28 / ダーク #FFAD5C
  • キャッチコピーは STORE_CM.md(セクション3)を単一ソースにして読み込み、画像側に文言を散らばせない。

ツール構成は Playwright ^1.49.0 + sharp ^0.33.5store_assets/package.json)、Flutter は >=3.44.0 です。生成(Flutter)と装飾(Node)を分けることで、「画面の中身」と「見せ方」を独立して差し替えられます。キャラを刷新したら生スクショを撮り直すだけ、コピーを直したら装飾だけ回すだけ、という運用になります。

ハマりどころ

  • Playwright が壊れていることがある。 node_modules の Playwright が動かないときは npm install で復旧します(Chromium 本体はキャッシュにあることが多い)。
  • 初回レンダリングでテキストが欠ける。 フォント読み込みの競合で、はんこ文字などが初回だけ抜けることがあります。同じコマンドで再レンダリングすれば直ります。
  • SNS 用画像(X ヘッダー・Instagram 投稿/ストーリーズ)も同じ発想で用意していますが、素材加工に使うライブラリが環境によって入っていないことがあるため、手元にある画像処理系(PIL など)に寄せて壊れにくくしています。

スキルにして「毎回同じ手順」にする

上記の一連(生スクショ撮影 → 装飾 → 書き出し)を Claude Code のスキルとして手順化しました。狙いは、リリースのたびに手順を思い出さなくても、同じ品質のストア画像が再現できること。属人的な「あの時どうやったか」を、実行可能な手順に落としておくのが効きました。

まとめ

  • ストアのスクショは golden テストの転用で実機なしに撮れる。速くて安定し、ダミーデータで「映える状態」を確定できる。
  • 装飾は 静的HTML + Playwright + sharp(Next.js 不要)。アセットは base64 埋め込み、コピーは STORE_CM.md を単一ソースに。「中身(Flutter)」と「見せ方(Node)」を分離すると片方だけで回せる。
  • 反復する制作工程は、スキル/スクリプトとして手順化しておくと、リリースのたびの負荷が大きく下がります。