開発ブログ

BLOG

練習の記録を、Friko 入りの画像にして共有できるようになりました

統計とお祝いの画面から、練習の記録を SNS に載せられる画像のカードを作れるようになった。Friko はその週の練習の様子で表情が変わり、レベルが上がって呼び名が変わるときは進化する。SNS の投稿画面を URL で開くと画像を添付できないため、画像をクリップボードに入れて貼ってもらう形にしたことと、ページの URL を投稿する形(OGP)に切り替える予定も書く。

公開 2026年10月12日

練習の記録を、画像のカードにして共有できるようになりました。カードは、統計の画面と、練習の達成を祝うお祝いの画面から作れます。あわせて、レベルが上がって呼び名(ビギナー・テンポマスターなど、レベルに応じて付く名前)が変わったときは、お祝いの画面でマスコットの Friko が進化し、姿が変わります。

横長の練習の記録のカード。左に音符を浮かべた Friko と「今週も練習中」、右にレベル(Lv. 27 テンポマスター)・直近 20 週の練習カレンダー・今週の練習時間・続けて練習した週の数・合計の練習時間
横長のカード(サンプルの記録で描いたもの)

カードを作る

メニューの「統計チャート」で統計の画面を開き、下にある「共有」を押すと、カードのプレビューが開きます。カードは、サインインしている人の練習の記録から作ります。

統計の画面の下の行。CLOSE の右に共有のボタンがある(1)
統計の画面の下
  1. 共有。押すとカードのプレビューが開く

カードの形は、Instagram などのストーリーに合う縦長と、横長から選べます。プレビューの下から SNS に投稿したり、画像を保存したりできます。

「練習の結果を共有」の画面。上にカードの形の切り替え(1)、真ん中にカードのプレビュー、その下に X・Threads・Bluesky のボタン(2)、いちばん下に画像を保存と共有のボタン(3)
「練習の結果を共有」の画面
  1. カードの形。縦長と横長を切り替える
  2. SNS の投稿画面を開く。同時にカードの画像をコピーするので、投稿欄に貼り付ける
  3. 画像を保存する・端末の共有の画面を開く

カードに載るもの

カードには、レベルと呼び名、今週の練習時間、続けて練習した週の数(週のストリーク)、合計の練習時間、1 日を 1 マスにした直近 20 週の練習カレンダーが載ります。統計の画面で週の目標を決めていれば、今週の進み具合も棒グラフで出ます。

名前やプロフィールのアイコンは載せていません。投稿すれば誰の練習かは SNS のアカウントでわかるので、カードに個人の情報を入れる必要はないと考えました。

カードの色は、表示設定で選んでいるアクセントカラー(アプリの強調の色)に合わせます。

縦長の練習の記録のカード。上に音符を浮かべた Friko と「今週も練習中」、その下にレベル、今週・続けて練習した週の数・合計の数字、直近 20 週の練習カレンダー
縦長のカード(ストーリー向け)

Friko の表情は今週の様子で変わる

カードの Friko は、その週の練習の様子に合わせて、表情と、まわりに描く小さな絵が変わります。たとえば今週も練習していれば、上のカードのように音符が浮かびます。

ほかにどんな表情があるかは、秘密です。練習を続けて、カードを作って確かめてみてください。

SNS に載せる

カードの画面から SNS に載せる方法は 2 つあります。

1 つめは、カードの画面の下の「共有」です。スマートフォンでは、押すと端末の共有の画面が開きます。ここで X や Instagram などのアプリを選ぶと、カードの画像を付けた状態で投稿の画面が開きます。

2 つめは、X・Threads・Bluesky のボタンです。スマートフォンでもパソコンでも、押すとそれぞれの投稿画面が開きます。投稿の文には、今週の練習時間・続けた週の数・レベルと、Metronome.fm の URL が入ります。

ただし、これらのボタンは投稿画面を URL で開くので、画像を添付できません。SNS 側が、URL に入れて渡せるものを文とリンクだけにしているためです。そこで、ボタンを押したときにカードの画像をクリップボードにコピーするようにしました。画像は投稿欄に自分で貼り付けます。パソコンなら、投稿欄で ⌘V(Ctrl+V)を押せば画像が付きます。

// 押した操作のままリンクで開き、同時に画像をコピーする(コピーの終わりは待たない)
<Link
  href={`https://x.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}`}
  target="_blank"
  rel="noopener noreferrer"
  onPress={() =>
    navigator.clipboard.write([new ClipboardItem({ "image/png": file })])
  }
>
  X
</Link>

この形に落ち着くまでに、iPhone で 2 つつまずきました。

  • 最初は、ボタンを押したあと画像のコピーが終わるのを待ってから、プログラムで新しいタブを開いていました。すると、X のアプリが入っていてもブラウザで開いてしまいました。iPhone がリンクをアプリに渡すのは、人がリンクを直接押したときだけです。そこで、ボタンそのものをリンクにして、押すとそのまま開くようにしました
  • X の投稿画面を開く URL には、intent/post と、古くからある intent/tweet があります。intent/post で開くと、X のアプリは開くものの、アプリの中のブラウザで Web 版が開いてログインを求められました。そのため intent/tweet を使っています

LINE には対応していません。最初は LINE のボタンもありましたが、LINE の投稿画面に画像を貼り付けられず、画像のない投稿しか作れなかったため、なくしました。

カードの描き方

カードは、ブラウザではなくサーバーで描いています。SNS にリンクを貼ったときに出るプレビューの画像(OG 画像)と同じ next/og(Satori)で、サインイン中の人の統計の記録から PNG を作ります。書体は、カードに描く文字の分だけを Google Fonts から読み込んでいます。

「今週」がいつかは、利用者のタイムゾーンで決まります。そこで、ブラウザから今日の日付を送ります。サーバーが受け付けるのは、UTC の今日の日付から前後 1 日までの値だけにしました。タイムゾーンは UTC-12〜UTC+14 なので、どこにいても正しい日付はこの前後 1 日に収まります。

お祝いの画面で Friko が進化する

再生を止めたときに、新しく達したもの(レベル・節目・週の目標)があると、紙吹雪つきのお祝いの画面が出ます。節目は、合計の練習時間や、続けて練習した週の数の区切りです。この画面にも Friko が出ます。

レベルが上がって呼び名が変わったときは、Friko が前の姿から進化します。進化のあいだは見出しが「おや? Friko のようすが……」に変わり、画面には Friko しかいません。

進化が始まるところ(次の姿が現れる前で止めている)

前の姿と次の姿のシルエットがだんだん速く入れ替わり、最後に次の姿が色付きで現れます。そこで初めて、レベルの数字と「共有」などのボタンが現れ、紙吹雪がはじけます。

進化が終わったお祝いの画面。Lv. 20、「テンポマスター」になりましたの見出し、テンポマスターの姿の Friko、Lv. 20 の数字、下に閉じる・統計を見る・共有のボタン(1)
進化が終わったところ
  1. 共有。押すとカードの画面が開く

この「共有」を押すと、統計から開くのと同じカードの画面が開きます。レベルが上がったその場でカードを作れます。

演出の作りにも少し触れておきます。進化の前後で画面の高さが変わらないよう、あとから出る数字やボタンは、消さずに場所を取ったまま見えなくしています。見出しも、進化のあいだの「おや? Friko のようすが……」と、進化のあとの見出しを同じ場所に重ねて、片方だけを見せています。

どの呼び名で Friko がどんな姿になるかも、秘密です。

URL を投稿するだけでカードが出る形に変えるかもしれません

今の形では、SNS の投稿画面に画像を自分で貼り付ける必要があります。この手間をなくすために、カードの扱いを変えることを考えています。

考えているのは、その時点の練習の記録を載せた公開のページを作り、そのページのプレビューの画像(OGP)をカードにする形です。

  • そのページの URL を投稿するだけで、X などではカードが大きな画像として表示されます。画像を添付しなくて済みます
  • 投稿がそのままページへのリンクになるので、見た人がカードの続きを見たり、Metronome.fm を試したりできます
  • カードに、任意のひとことを添えられるようにしたいと考えています

そうなれば、共有の画面の SNS のボタンは、そのページの URL を投稿する形に替わるかもしれません。公開する範囲や、ひとことの扱いを決めてから進めます。

この記事を共有

X でポストはてなブックマーク