はじめに:動機が全て
正直に書きます。
「自分の描いたキャラクターに、合計金額を言わせたかった」 ただそれだけです。
うちには25年「うちの子」という概念でいる自作キャラクター「浅葱優」がいます。
5月16日AIキャラクターフェスティバルに出展するにあたって、「会計のときにうちの子が金額を伝えてくれたらかわいいよな……」という完全にオタク由来の発想から、このWEB電卓を作りました。
技術的にはVanilla JS + 静的HTML構成なので、Qiitaで技術記事として公開するのが正しいのかどうか若干悩みましたが、「動機は最高にオタクだけど実装は真面目」 という記事があってもいいと思うので書きます。
作ったもの
キャラクター電卓(Character Calculator)
好きなキャラクター画像を1枚差し替えるだけで、そのキャラクターが合計金額・おつりを表示してくれるWEB電卓アプリです。
機能
購入モード
商品金額を次々と入力し、= を押すたびに合計に加算されていきます。複数商品の合計を出すレジ的な使い方です。
500 [=] → 合計 500円
300 [=] → 合計 800円
おつりモード
合計値を覚えておき、おつりモードでおつりを購入者へと見せる設計。
1000 [-] 800 [=] → おつり 200円
設計の話
構成:依存ゼロの静的3ファイル
dentaku/
├── index.html
├── style.css
├── script.js
└── dentaku.png ← ここを差し替えるだけ
外部ライブラリなし。npm install も不要。index.html をブラウザで開くだけで動きます。
この構成にしたのはオフライン環境での動作を最優先にしたからです。イベント会場はWi-Fiが不安定なことが多い。サーバーもAPIも使わず、ZIPを展開してブラウザに投げれば動く、という状態が理想でした。
ステートの持ち方
let currentInput = '';
let previousInput = '';
let operation = null;
let total = 0;
let mode = 'purchase'; // 'purchase' | 'change'
購入モードでは total に数値を加算し続けるだけ。おつりモードでは previousInput(預かり金額)と currentInput(お会計)の2値を保持して差分を出す、というシンプルな構造にしました。
モード切り替え時はステートをリセットします。
function switchMode(newMode) {
mode = newMode;
clearCalculator();
total = 0;
updateTotalDisplay();
purchaseModeBtn.classList.toggle('active', mode === 'purchase');
changeModeBtn.classList.toggle('active', mode === 'change');
}
対面レイアウト
タブレットを机に平置きして、キャラクター側をお客さんに向ける運用を想定しています。右パネルを transform: scaleY(-1) で上下反転させることで、机を挟んで向かい合った相手がちょうど正面から読める状態にしています。
.right-panel {
transform: scaleY(-1);
}
地味ですが、これが対面販売シーンでの没入感にいちばん効いています。
ネオンエフェクト
ボタンを押したときのCSS Animationです。単調になりがちな会計待ち時間に少しだけ遊び心を。
@keyframes numberPress {
0% { background-color: #004466; box-shadow: 0 0 0 0 rgba(0,255,255,0.7); }
25% { background-color: #00ffff; box-shadow: 0 0 10px 5px rgba(0,255,255,0.7); }
50% { background-color: #ff00ff; box-shadow: 0 0 10px 5px rgba(255,0,255,0.7); }
75% { background-color: #ffff00; box-shadow: 0 0 10px 5px rgba(255,255,0,0.7); }
100% { background-color: #004466; box-shadow: 0 0 0 0 rgba(0,255,255,0.7); }
}
カスタマイズ:画像を差し替えるだけ
これが最大のポイントで、かつ作った理由の全てでもあります。
- リポジトリをダウンロード(ZIP可)
- 好きなキャラクターの画像を用意し、ファイル名を
dentaku.pngに変更 - フォルダ内の
dentaku.pngと上書き -
index.htmlをブラウザで開く
推奨:透過PNG形式。背景色に溶け込んでキャラクターだけが浮き上がります。
ネット環境がない場所でも使える
「静的ファイル構成」の恩恵として、完全オフラインで動作します。
ZIPをダウンロード → 展開 → index.html をブラウザで開く → 動く
USB一本持ち込んでおけばWi-Fi不要です。会場の回線状況を気にしなくていい安心感は、思った以上に大きかったです。
反省点・今後
-
おつりモードのUXが若干わかりにくい。
-ボタンで区切る操作は直感的でないかもしれないので、ウィザード形式(「預かり金額を入力」→「お会計を入力」)にする案もある -
数字の桁区切りがない。10万円超の会計だと
100000が並んで読みにくい。toLocaleString()を入れるだけなのでいずれ対応したい - キャラクター画像の表示サイズ調整がCSSのみなので、縦長・横長の画像によっては見栄えに差がある
おわりに
「推しに合計金額を言わせたい」という動機は最高にオタクですが、「一枚の画像差し替えだけで誰でも自分の推し電卓が作れる」 という形にできたのは、結果的に良かったと思っています。
同じようにイベント出展するオタクの方、自作キャラがいる方、推しがいる方、ぜひ dentaku.png を差し替えて使ってみてください。
🄫 sugerpowderflower2026 / 改変自由・利用責任は利用者に帰属
なお、私の方の電卓はPOSレジ方式なのは当日のお楽しみです!
