こんにちはハッピーサトです。
手焙煎(ドラム、手網、鍋焙煎など)用のシンプルな焙煎記録アプリを作りました。
普段は手書きで焙煎記録を残していますが、焙煎中は手がなかなか離せないですし、スマホ画面で簡単に綺麗に記録を残せたらとの気持ちで開発しました。
良かったら使って下さい☆彡
使い方
ストップウォッチの要領で各ボタンを押するだけで1、2ハゼ、煎り止め時間をタイマーに記録できます。
※リセット機能
「Stop Reset」ボタンは3回押すとタイマーと記録を消去しリセットできます
※1,2ハゼは各2回まで記録可能
「さっきのは正式なハゼじゃない」という時にボタンを再度押せば2回目の記録も残ります
※2ハゼに入れない焙煎の記録
浅・中煎りなど2ハゼに入れない焙煎は「Start」「1st Crack」「Stop Reset」の順に進めればOKです
コーヒー自家焙煎タイマー
00:00
プログラム内容
アプリのHTML、CSS、JAVAコードを公開しておきます。
8バッチ記録可能Versionも該当ページに公開しておきます。
HTMLコード
<div id="timer-container"> <div id="timer-display">00:00</div> <div id="buttons-container"><button id="start">Start</button><br /><button id="first-crack">1st<br />Crack</button><br /><button id="second-crack">2nd<br />Crack</button><br /><button id="stop-reset">Stop<br />Reset (×3)</button></div> <div id="crack-times"> </div> </div> <p><script src="script.js"></script></p>
CSSコード
#timer-container { font-family: Arial, sans-serif; text-align: center; } #timer-title { font-size: 24px; font-weight: bold; } #timer-display { background-color: black; color: white; font-size: 36px; padding: 20px; margin: 10px 0; } #buttons-container { display: flex; justify-content: center; } button { background-color: #8B4513; color: white; border: none; padding: 10px 20px; margin: 5px; font-size: 16px; cursor: pointer; } button:hover { background-color: #A0522D; }
JAVAコード
document.addEventListener('DOMContentLoaded', function() { let startTime = 0; let timerInterval = null; let firstCrackTimes = []; let secondCrackTimes = []; let stopTime = 0; let resetCount = 0; function formatTime(time) { const minutes = Math.floor(time / 60000).toString().padStart(2, '0'); const seconds = ((time % 60000) / 1000).toFixed(0).padStart(2, '0'); return `${minutes}:${seconds}`; } function updateTimerDisplay(time) { document.getElementById('timer-display').textContent = formatTime(time); } function updateCrackTimesDisplay() { const firstCracks = firstCrackTimes.map(t => formatTime(t)).join(', '); const secondCracks = secondCrackTimes.map(t => formatTime(t)).join(', '); const stopDisplay = stopTime ? `Stop: ${formatTime(stopTime)}` : ''; document.getElementById('crack-times').innerHTML = [ firstCracks ? `1st Crack: ${firstCracks}` : '', secondCracks ? `2nd Crack: ${secondCracks}` : '', stopDisplay ].filter(Boolean).join('<br>'); // 改行を<br>タグで表現 } function startTimer() { if (!timerInterval) { startTime = Date.now() - (stopTime ? stopTime : 0); timerInterval = setInterval(() => { updateTimerDisplay(Date.now() - startTime); }, 1000); } } function recordCrack(crackArray) { if (timerInterval && crackArray.length < 2) { crackArray.push(Date.now() - startTime); updateCrackTimesDisplay(); } } function stopResetTimer() { if (timerInterval) { clearInterval(timerInterval); stopTime = Date.now() - startTime; timerInterval = null; updateCrackTimesDisplay(); resetCount = 0; } else { resetCount++; if (resetCount === 3) { document.getElementById('timer-display').textContent = '00:00'; firstCrackTimes = []; secondCrackTimes = []; stopTime = 0; updateCrackTimesDisplay(); resetCount = 0; } } } document.getElementById('start').addEventListener('click', startTimer); document.getElementById('first-crack').addEventListener('click', () => recordCrack(firstCrackTimes)); document.getElementById('second-crack').addEventListener('click', () => recordCrack(secondCrackTimes)); document.getElementById('stop-reset').addEventListener('click', stopResetTimer); });