Receipt.js
Web Serial API でレシートプリンター (サーマルプリンター) が動きます。
https://github.com/receiptline/receiptjs
印刷データはレシートマークダウン。難しいコマンド制御は不要です。
https://marketplace.visualstudio.com/items?itemName=receiptline.receipt-markdown
ユーザーの操作
「つなぐ・ひらく・えらぶ」の 3 ステップ。
Bluetooth でつなぐ
Web ページを開く
PC 版 Chrome (Edge, Opera) に対応。
プリンターを選ぶ
印刷機能の追加
Web アプリ (Web サイト) への追加も簡単。
印刷データを作る
Receipt.js Designer または VS Code 拡張機能 で編集します。
HTML に組み込む
<script type="text/javascript" src="script/receipt.js"></script>
<script type="text/javascript" src="script/receipt-printer.js"></script>
<script type="text/javascript" src="script/receipt-serial.js"></script>
<script type="text/javascript" src="script/qrcode-generator/qrcode.js"></script>
ライブラリ本体と、オプションのコマンド変換、シリアル通信、二次元コードです。
スクリプトを追加する
document.querySelector('button').onclick = () => {
const markdown = `
^^電子チケット控え
-
紛失しないよう十分ご注意ください
{code:NPCCMLIN20230723180001123901;option:qrcode,8,h}
1階 12列 39番
`;
const conn = ReceiptSerial.connect();
conn.on('ready', async () => {
await conn.print(markdown);
conn.close();
});
};
数行の JavaScript で接続して、印刷して、切断。
例のインスタントカメラ
過去記事「簡単レシート印刷 receiptline と 20 行の JavaScript でレジプリンターをインスタントカメラにしてみた」のコードを修正。
Chromebook で実行
Chromebook のブラウザだけで完結。Node.js は不要です。
撮影&プリント
画像をタップして撮影・プリント。接続されていない場合はポートを選択します。
ソースコード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Instant Camera</title>
<script type="text/javascript" src="script/receipt.js"></script>
<script type="text/javascript" src="script/receipt-printer.js"></script>
<script type="text/javascript" src="script/receipt-serial.js"></script>
<!--<script type="text/javascript" src="script/qrcode-generator/qrcode.js"></script>-->
<script type="text/javascript">
async function initialize() {
const video = document.querySelector('video');
const canvas = document.querySelector('canvas');
let conn = null;
// video
video.srcObject = await navigator.mediaDevices.getUserMedia({ audio: false, video: true });
video.onloadedmetadata = event => {
canvas.height = Math.trunc(canvas.width * video.videoHeight / video.videoWidth);
};
video.onclick = event => {
// image
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
let data = `{i:${canvas.toDataURL('image/png').slice(22)}}\n`;
// date
const now = new Date();
data += `${new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString()}|`;
// print
if (conn) {
conn.print(data, '-g 1.8');
}
else {
conn = ReceiptSerial.connect();
const timeout = setTimeout(conn.close, 15000);
conn.on('disconnect', () => {
conn = null;
});
conn.on('ready', () => {
clearTimeout(timeout);
conn.print(data, '-g 1.8');
});
}
};
}
</script>
</head>
<body onload="initialize()">
<video autoplay style="width: 100%;"></video>
<canvas width="576" height="432" style="display: none;"></canvas>
</body>
</html>
以上です。ではまた!