Skip to content

Instantly share code, notes, and snippets.

@eight
Created December 24, 2025 03:11
Show Gist options
  • Select an option

  • Save eight/48c8068436016b470b276c0d18062047 to your computer and use it in GitHub Desktop.

Select an option

Save eight/48c8068436016b470b276c0d18062047 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Barcode Scanner Tool</title>
<!-- html5-qrcode ライブラリを読み込み -->
<script src="https://unpkg.com/html5-qrcode" type="text/javascript"></script>
<style>
body {
font-family: sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
h1 {
text-align: center;
color: #333;
}
#reader {
width: 100%;
background-color: #000;
border-radius: 8px;
overflow: hidden;
}
#result-area {
margin-top: 20px;
padding: 15px;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.last-scan {
font-size: 1.5em;
font-weight: bold;
color: #2563eb;
text-align: center;
padding: 10px;
border-bottom: 2px solid #eee;
}
.history {
margin-top: 10px;
max-height: 200px;
overflow-y: auto;
}
.history-item {
padding: 5px 0;
border-bottom: 1px solid #eee;
color: #666;
font-size: 0.9em;
display: flex;
justify-content: space-between;
}
.timestamp {
color: #999;
font-size: 0.8em;
}
button {
width: 100%;
padding: 10px;
margin-top: 10px;
background-color: #dc2626;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
</head>
<body>
<h1>📦 Fab Scanner</h1>
<div id="reader"></div>
<div id="result-area">
<div class="last-scan" id="last-result">スキャン待機中...</div>
<div class="history" id="scan-history">
<!-- 履歴がここに追加されます -->
</div>
<button onclick="clearHistory()">履歴をクリア</button>
</div>
<script>
// 読み取り成功時のコールバック
function onScanSuccess(decodedText, decodedResult) {
console.log(`Code matched = ${decodedText}`, decodedResult);
// 最新の結果を表示
const lastResultEl = document.getElementById('last-result');
// 直前の値と同じなら連続追加しない(1秒以内の重複防止用など簡易ロジック)
if (lastResultEl.dataset.lastText === decodedText &&
Date.now() - parseInt(lastResultEl.dataset.lastTime || 0) < 2000) {
return;
}
// 表示更新
lastResultEl.innerText = decodedText;
lastResultEl.dataset.lastText = decodedText;
lastResultEl.dataset.lastTime = Date.now();
// 効果音(ビープ音)
playBeep();
// 履歴に追加
addToHistory(decodedText, decodedResult.result.format?.formatName || 'Unknown');
}
function onScanFailure(error) {
// 読み取り失敗は頻繁に発生するため、通常はログに出さないか無視する
// console.warn(`Code scan error = ${error}`);
}
// 履歴追加ロジック
function addToHistory(text, format) {
const historyEl = document.getElementById('scan-history');
const item = document.createElement('div');
item.className = 'history-item';
const timeStr = new Date().toLocaleTimeString();
item.innerHTML = `
<span>${text} <small>(${format})</small></span>
<span class="timestamp">${timeStr}</span>
`;
// 先頭に追加
historyEl.insertBefore(item, historyEl.firstChild);
}
// 履歴クリア
function clearHistory() {
document.getElementById('scan-history').innerHTML = '';
document.getElementById('last-result').innerText = 'スキャン待機中...';
}
// 簡易ビープ音
function playBeep() {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);
oscillator.type = 'square';
oscillator.frequency.setValueAtTime(880, audioCtx.currentTime); // A5
gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime);
oscillator.start();
oscillator.stop(audioCtx.currentTime + 0.1);
}
// スキャナー初期化
// QRコードと、一般的な1次元バーコードをサポート設定
// html5-qrcode はデフォルトでこれらをサポートしていますが、明示的に書くことも可能
let html5QrcodeScanner = new Html5QrcodeScanner(
"reader",
{
fps: 10,
qrbox: { width: 250, height: 150 }, // バーコード用に横長
aspectRatio: 1.0
},
/* verbose= */ false
);
html5QrcodeScanner.render(onScanSuccess, onScanFailure);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment