⬅ ギャラリーに戻る
✏️ '
timer.html
' を修正中... (終わったら保存を押してね)
📷 素材アップロード
アップロード
🛠️ プログラム作成
[修正モード]
ファイル名:
.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>わんわん応援タイマー</title> <link href="https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c:wght@400;700&display=swap" rel="stylesheet"> <style> :root { --primary-color: #8D6E63; /* 犬の茶色 */ --accent-color: #FF7043; /* 首輪の赤 */ --bg-color: #FFF3E0; /* 背景の薄オレンジ */ --text-color: #5D4037; } body { font-family: 'M PLUS Rounded 1c', sans-serif; background-color: var(--bg-color); color: var(--text-color); display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; margin: 0; overflow: hidden; /* スクロール防止 */ } h1 { margin: 0 0 20px 0; font-size: 1.5rem; } /* --- ビジュアルエリア --- */ .stage { position: relative; width: 320px; height: 280px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; } /* わんちゃん */ .dog { font-size: 100px; margin-bottom: 10px; transition: transform 0.3s; cursor: pointer; z-index: 10; } /* 応援中のアニメーション:しっぽを振るイメージ */ .dog.working { animation: bounce 0.6s infinite alternate; } @keyframes bounce { 0% { transform: translateY(0) rotate(0deg); } 100% { transform: translateY(-10px) rotate(5deg); } } /* 吹き出し */ .bubble { position: absolute; top: 10px; background: #fff; padding: 10px 20px; border-radius: 30px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); font-weight: bold; opacity: 0; transition: opacity 0.3s, transform 0.3s; transform: translateY(10px); } .bubble.show { opacity: 1; transform: translateY(0); } .bubble::after { content: ''; position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%); border: 10px solid transparent; border-top-color: #fff; } /* ご飯エリア */ .food-area { position: relative; width: 200px; height: 80px; display: flex; justify-content: center; align-items: flex-end; } .bowl { width: 140px; height: 40px; background: #D84315; border-radius: 0 0 70px 70px; z-index: 2; position: relative; } /* カリカリ(ドッグフード) */ .food-pile { position: absolute; bottom: 30px; width: 120px; height: 0px; /* JSで制御 */ background: #795548; border-radius: 50% 50% 10% 10%; z-index: 1; transition: height 0.5s ease; background-image: radial-gradient(#A1887F 20%, transparent 20%); background-size: 15px 15px; } /* --- タイマー操作エリア --- */ .timer-display { font-size: 3.5rem; font-weight: bold; color: var(--primary-color); margin: 10px 0; font-feature-settings: "tnum"; } .controls { display: flex; gap: 15px; margin-top: 10px; } input[type="number"] { padding: 8px; border-radius: 10px; border: 2px solid #ccc; width: 60px; text-align: center; font-size: 1.2rem; outline: none; } input:focus { border-color: var(--accent-color); } button { padding: 10px 24px; border: none; border-radius: 50px; font-size: 1.1rem; font-weight: bold; cursor: pointer; font-family: inherit; transition: transform 0.1s; } button:active { transform: scale(0.95); } .btn-start { background-color: var(--accent-color); color: white; } .btn-reset { background-color: #E0E0E0; color: #555; } .input-group { display: flex; align-items: center; gap: 5px; margin-bottom: 10px; } /* 音声テストボタン(デバッグ用) */ .sound-test { margin-top: 30px; font-size: 0.8rem; color: #888; text-decoration: underline; cursor: pointer; } </style> </head> <body> <h1>わんわん応援タイマー 🐶</h1> <div class="stage"> <div class="bubble" id="messageBubble">準備オッケー!</div> <div class="dog" id="dog">🐶</div> <div class="food-area"> <div class="food-pile" id="foodPile"></div> <div class="bowl"></div> </div> </div> <div id="setupArea"> <div class="input-group"> <input type="number" id="inputMin" value="25" min="0" max="180"> <span>分</span> <input type="number" id="inputSec" value="00" min="0" max="59"> <span>秒</span> </div> </div> <div class="timer-display" id="timerDisplay">25:00</div> <div class="controls"> <button class="btn-start" id="startBtn" onclick="toggleTimer()">スタート</button> <button class="btn-reset" onclick="resetTimer()">リセット</button> </div> <div class="sound-test" onclick="testSound()">🔊 音量テスト(終了の音)</div> <script> // ============================================ // 🛠️ 設定エリア:音声ファイル名をここで指定します // ============================================ // スタートボタンを押した時の音 const START_SOUND_FILE = 'bark.mp3'; // タイマー終了時の音 const ALARM_SOUND_FILE = 'alarm.mp3'; // ============================================ const MEDIA_PATH = 'media/'; // mediaディレクトリのパス let timerInterval; let totalSeconds = 0; let remainingSeconds = 0; let isRunning = false; // DOM要素の取得 const dog = document.getElementById('dog'); const foodPile = document.getElementById('foodPile'); const bubble = document.getElementById('messageBubble'); const timerDisplay = document.getElementById('timerDisplay'); const startBtn = document.getElementById('startBtn'); const inputMin = document.getElementById('inputMin'); const inputSec = document.getElementById('inputSec'); const setupArea = document.getElementById('setupArea'); // 音声オブジェクトの作成関数 function playAudio(filename) { // ファイル名が空なら何もしない if(!filename) return; const path = MEDIA_PATH + filename; const audio = new Audio(path); // 再生を試みる(ファイルがない場合のエラー対策) audio.play().catch(e => { console.log("音声再生エラー: " + filename + " が見つからないか、ブラウザがブロックしました。", e); // 音が出なくてもアプリが止まらないようにする }); } // 初期表示更新 updateTimerText(parseInt(inputMin.value) * 60); // 入力欄の変更監視 inputMin.addEventListener('change', updateInputPreview); inputSec.addEventListener('change', updateInputPreview); function updateInputPreview() { let m = parseInt(inputMin.value) || 0; let s = parseInt(inputSec.value) || 0; updateTimerText(m * 60 + s); } // スタート・一時停止ボタン function toggleTimer() { if (isRunning) { pauseTimer(); } else { startTimer(); } } function startTimer() { if (remainingSeconds === 0 && !timerInterval) { // 初回スタート時の設定 let m = parseInt(inputMin.value) || 0; let s = parseInt(inputSec.value) || 0; totalSeconds = m * 60 + s; remainingSeconds = totalSeconds; if (totalSeconds <= 0) return; // スタート音を再生 playAudio(START_SOUND_FILE); } if (remainingSeconds <= 0) return; isRunning = true; startBtn.textContent = "待て!(一時停止)"; setupArea.style.display = 'none'; // 入力欄を隠す dog.classList.add('working'); // アニメーション開始 showMessage("よし、頑張るワン!"); timerInterval = setInterval(() => { remainingSeconds--; updateTimerText(remainingSeconds); updateVisuals(); if (remainingSeconds <= 0) { timerFinished(); } }, 1000); updateVisuals(); // 即時反映 } function pauseTimer() { isRunning = false; clearInterval(timerInterval); startBtn.textContent = "再開"; dog.classList.remove('working'); showMessage("休憩? 待ってるワン..."); } function resetTimer() { pauseTimer(); startBtn.textContent = "スタート"; setupArea.style.display = 'block'; // リセット処理 let m = parseInt(inputMin.value) || 0; let s = parseInt(inputSec.value) || 0; remainingSeconds = 0; totalSeconds = 0; timerInterval = null; updateTimerText(m * 60 + s); foodPile.style.height = '0px'; showMessage(""); } function timerFinished() { clearInterval(timerInterval); isRunning = false; startBtn.textContent = "完了!"; dog.classList.remove('working'); updateTimerText(0); foodPile.style.height = '0px'; // 完食 // 完了メッセージと音 showMessage("ワオーン!(すごーい!)"); dog.textContent = "😍"; // 顔を変える playAudio(ALARM_SOUND_FILE); // 3秒後に顔を戻す setTimeout(() => { dog.textContent = "🐶"; }, 3000); } // 表示の更新 function updateTimerText(sec) { const m = Math.floor(sec / 60); const s = sec % 60; timerDisplay.textContent = `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`; } // ビジュアル(ご飯の山)の更新 function updateVisuals() { if (totalSeconds <= 0) return; // 残り時間の割合 const ratio = remainingSeconds / totalSeconds; // 時間=ご飯の量。時間が減る=食べて減る // 最大高さ設定(時間は長いほど山盛りに) let maxPileHeight = 30 + (totalSeconds / 60) * 1.5; if (maxPileHeight > 100) maxPileHeight = 100; const currentHeight = maxPileHeight * ratio; foodPile.style.height = `${currentHeight}px`; // 応援メッセージの変化 if (ratio < 0.2 && ratio > 0) { showMessage("あとちょっとワン!"); } } // 吹き出し制御 function showMessage(text) { if (!text) { bubble.classList.remove('show'); return; } bubble.textContent = text; bubble.classList.add('show'); } // 音声テスト用 function testSound() { playAudio(ALARM_SOUND_FILE); showMessage("音のテスト中ワン!"); } </script> </body> </html>
上書き保存する
キャンセルして新規作成に戻る
📂 APP の作品
ProVocab - 縦スクロール暗記版
eigo2.html (01/15 10:37)
✏️ 修正
🌏 公開
🗑️
ProVocab - 語源マスター版
eigo.html (01/15 10:37)
✏️ 修正
🌏 公開
🗑️
進化版!わんわんタイマー
timer3.html (01/14 13:38)
✏️ 修正
🌏 公開
🗑️
わんわん応援タイマー
timer.html (01/14 12:49)
✏️ 修正
🌏 公開
🗑️
進化版!わんわんタイマー
timer2.html (01/14 12:17)
✏️ 修正
🌏 公開
🗑️