Home

Plate Calculator

目標の重量を入れると、バーベルの片側に着けるプレートの構成を計算する Web アプリ。
パワーリフティングの競技者本人が、自分で使うために作りました。

iPhoneのSafariで開いたプレート計算機。明るい画面で、目標104.5kgに対して片側44.75kgのプレート構成が色つきで表示されている 同じ画面を暗い表示にしたもの。背景が黒くなり、プレートの色はそのまま見分けられる
実際のiPhoneで公開URLを開いたところ。同じ画面が、端末の設定に合わせて明るさを切り替えます。

なぜ作ったか

ジムでバーベルを組むとき、何をどう着けるかは毎回計算が必要です。 ちょうど 100kg なら暗算できますが、記録を伸ばすには 2.5kg、1kg と細かく刻んでいくことになります。 そして追い込んだ直後の息が上がった状態では、その簡単な計算を間違えます。プレートの着け間違いは事故につながります。

もうひとつ、パワーリフティングの大会現場では PC 1 台の画面をプロジェクターに映す方式が使われています。 Web アプリにすれば、その場にいる全員が手元のスマートフォンから確認できます。

このアプリはその両方を出発点にしています。 数字を読まなくても色と枚数で確認できること、片手で数タップで済むこと、 そしてそのジムにあるプレートで実際に組める重量しか表示しないことを優先して作りました。

目標重量142.5kgに対し、片側61.25kgのプレート構成が色つきの図で表示されている画面
142.3 と入力しても 142.5kg に丸まります。画面の数字と計算結果は必ず一致します。

数字で見る

0 ms

Total Blocking Time

タップした瞬間に反応する

0

Cumulative Layout Shift

読み込み中にボタンが動かない

32

テストケース

計算が正しいことを機械が毎回チェックする

68.5 kB

初回の読み込み

写真1枚ぶんの通信で開き終わる

Lighthouse は4項目すべて100点。本番で読み込む外部ライブラリは React と React DOM の2つだけです。 コードを直すたびに、整形・テスト・ビルドの全チェックが18〜20秒で自動的に走ります。

Lighthouseの測定結果。パフォーマンス・ユーザー補助・おすすめの方法・SEOの4項目がすべて100点
Google の Lighthouse による本番URLの計測結果(モバイル)。

設備に合わせて変えられる

ジムによって置いてあるプレートは違います。25kg のプレートがない、 規定の色ではない、そもそも重さの種類が少ない。

このアプリは「使えるプレート」を先に設定してから計算します。 自分のジムの設備に合わせておけば、実際に組める構成だけが表示されます

環境設定を開いた画面。バーの重さ、カラーの有無、使えるプレートの種類を選ぶボタンが並んでいる
使えるプレートを選ぶと、入力できる重量の刻みが自動で変わります(この画面では0.5kg単位)。

工夫したこと

  • 暗い画面でも明るい画面でも、9色すべてのプレートがきちんと見えるように設計した
  • 画面を読み上げるソフト(視覚障害のある方が使う)でも操作できるようにした
  • 計算部分だけを切り出して自動テストを書き、間違った計算をしていないことを機械が毎回チェックする仕組みにした

調べて、測って直した

仕様を決めるとき、参考サイトではなく国際連盟(IPF)が出している英語の公式ルールブック(44ページ)を直接読みました。 その結果、参考記事をもとに書いていた仕様の間違いが2つ見つかりました。 記録更新の最小幅は 0.25kg ではなく 0.5kg だったこと。そして 1kg のプレートが実装から抜けていたことです。

なぜ 0.5kg が下限なのかは、物理で説明できます。 バーベルは左右対称なので、合計重量は「片側に足した分の2倍」でしか動きません。 合計 +0.25kg は片側 +0.125kg になりますが、そんなプレートは存在しない。 ルールが 0.5kg を下限にしているのは、必然だったわけです。

もうひとつ。暗い画面にしたとき、黒いプレートが背景に埋もれて見えなくなっていました。 見た目で気づいたのではなく、コントラスト比を測って見つけた問題です。 測定値は 1.11:1。アクセシビリティの基準(WCAG)が求める 3:1 を大きく下回っていました。

対処として「溶けそうな色を個別に指定する」こともできましたが、それでは想定していない色でまた同じことが起きます。 全プレート共通の輪郭を1つ定義する形に設計を変えたところ、9色すべて・明暗どちらのモードでも自動的に成立するようになり、 コードはむしろ短くなりました

技術と開発プロセス

フレームワーク
React 19 / TypeScript
ビルド
Vite
スタイル
Tailwind CSS v4(CSS変数でデザイントークンを管理)
テスト
Vitest(32ケース)
CI
GitHub Actions(ESLint / Prettier / テスト / ビルド)
ホスティング
Vercel
  • GitHub Flow で運用。main は常にデプロイできる状態を保ち、作業はブランチと Pull Request で進める
  • CI でコード整形・テスト・ビルドの全通過を必須にしている
  • 工程ごとに見積時間と実績時間を記録し、差が出た理由を残している

たとえば README の整備は見積3時間に対して実績1時間でした。 設計判断・スクリーンショット・測定値を開発中に記録していたので、「何を書くか」を考える時間がゼロだったためです。

これから

今のバージョンは重量計算だけです。

この先は大会の進行支援まで広げたいと思っています。 選手名簿や、次の挑戦重量の表示など、個人や事務局の規模で開かれる大会で使えるところまで。

作りながら考えている段階なので、形は変わるかもしれません。

実際に触ってみてください