cara membuat countdown timer html

cara membuat countdown timer html live online countdown timer
Kalian pernah tidak butuh alat untuk menhitung waktu mundur untuk berbagai kegiatan di pekerjaan kalian, misalnya untuk ujian secara manual, atau online? jika anda butuh maka tentunya anda membutuhkan countdown timer seperti yang telah dialami juga oleh penulis sendiri menggunakan countdown timer untuk ujian diruang kuliah besar dari pda kita mengingatkan maka saya membuat alat tersebut di tampilkan di layar depan ruangan. Nah pada kesempatan ini saya akan membawah mengenai hal tersebut mulai dari pengerian hingga rekomendasi yang bebas digunakan.

Apa Itu Countdown Timer? 
Countdown timer merupakan alat atau fitur yang berfungsi untuk menhitung waktu mundur dari durasi yang telah di tentutkan sampai waktu selesai atau 0. Berbeda dengan stopwacth yang menghitung waktu maju 

Fungsi Countdown Timer 
Countdown timer dapat digunakan untuk kegiatan kehidupan sehari-hari seperti: 
  1. Mengatur Waktu Aktivitas memasak, olah raga, belajar atau ujian yang seperti pengalaman yang saya sampaikan

  2. Presentasi dan Kelas dimana untuk mempermudah dalam menghitung durasi maka pada layar presentasi ditampilkan coundtown timer
  3. Manajemen Tugas yang membantu kita lebih tepat waktu dalam mengerjakan tugas
  4. Event Countdown timer untuk menghitung waktu mundur pada sebuah event 
Jenis-Jenis Countdown Timer 
Berikut adalah jenis countdwn timer dilihat dari paltform yang digunakan 
  1. Website jenis ini Bisa dipakai langsung tanpa instalasi dengan menampilkannya dibrowser, ada mode full screen seperti pada Contoh Countdown Timer Web Online
  2. Aplikasi Mobile ditampilkan pada widget di layar utama pada mobile
  3. Ekstensi Browser biasanya akan ditampilkan pada toolbar chrome
  4. Desktop App bisa digunakan secara offline di sistem operasi namun biasanya perlu instalasi jika berdasarkan 
Cara membuat countdown timer online
Untuk membuat countdown timer anda bisa menggunakan skrip kode di bawah ini yang disimpan dalam ektensi .html selanjutnya anda bisa membukanya dibrowser
<!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Countdown Timer - Setting Waktu</title> <style> /* Reset & Base */ * { margin: 0; padding: 0; box-sizing: border-box; } body { min-height: 100vh; display: flex; justify-content: center; align-items: center; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #0c0e1a 0%, #1a1f33 50%, #0f1424 100%); padding: 1.5rem; position: relative; overflow-x: hidden; } /* Efek background bintang */ body::before { content: ''; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-image: radial-gradient(2px 2px at 20px 30px, #eee, transparent), radial-gradient(2px 2px at 40px 70px, rgba(255,255,255,0.8), transparent), radial-gradient(2px 2px at 50px 160px, #ddd, transparent), radial-gradient(2px 2px at 90px 40px, rgba(255,255,255,0.6), transparent), radial-gradient(2px 2px at 130px 80px, #fff, transparent), radial-gradient(1px 1px at 160px 120px, #eee, transparent), radial-gradient(2px 2px at 200px 50px, rgba(255,255,255,0.7), transparent); background-size: 200px 200px; background-repeat: repeat; opacity: 0.3; pointer-events: none; z-index: 0; } /* Kartu utama */ .card { position: relative; z-index: 1; max-width: 720px; width: 100%; background: rgba(18, 24, 45, 0.85); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-radius: 60px; padding: 2.5rem 2.5rem 2.8rem; border: 1px solid rgba(255, 255, 255, 0.08); box-shadow: 0 30px 60px -15px rgba(0, 0, 0, 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.05); transition: transform 0.3s ease, box-shadow 0.3s ease; } .card:hover { transform: translateY(-3px); box-shadow: 0 40px 70px -15px rgba(0, 0, 0, 0.9); } /* Header */ .header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.8rem; padding-bottom: 1.2rem; border-bottom: 1px solid rgba(255, 255, 255, 0.06); } .header-left { display: flex; align-items: center; gap: 0.8rem; } .header-left i { font-size: 1.8rem; color: #6c8cff; background: rgba(108, 140, 255, 0.12); padding: 0.6rem; border-radius: 16px; border: 1px solid rgba(108, 140, 255, 0.15); } .header-left h1 { font-size: 1.5rem; font-weight: 700; color: #e8eeff; letter-spacing: -0.02em; } .header-left h1 span { color: #6c8cff; } .badge { background: rgba(108, 140, 255, 0.15); padding: 0.3rem 1rem; border-radius: 40px; font-size: 0.7rem; color: #a8bfff; border: 1px solid rgba(108, 140, 255, 0.2); font-weight: 500; letter-spacing: 0.3px; text-transform: uppercase; } /* Timer Display */ .timer-display { text-align: center; padding: 1rem 0 1rem; margin-bottom: 1.5rem; } .timer-numbers { font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 5.2rem; font-weight: 700; letter-spacing: 0.08em; background: linear-gradient(135deg, #f0f4ff 0%, #8aa8ff 100%); -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: 0 0 40px rgba(108, 140, 255, 0.15); line-height: 1.2; transition: all 0.2s; } .timer-label { font-size: 0.85rem; color: #7a8db5; letter-spacing: 0.15em; text-transform: uppercase; margin-top: 0.3rem; font-weight: 400; } .timer-progress { width: 100%; height: 4px; background: rgba(255, 255, 255, 0.06); border-radius: 10px; margin-top: 1.8rem; overflow: hidden; position: relative; } .timer-progress-bar { height: 100%; width: 100%; background: linear-gradient(90deg, #6c8cff, #a78aff); border-radius: 10px; transition: width 0.3s linear; box-shadow: 0 0 20px rgba(108, 140, 255, 0.3); } /* Setting Waktu - Jam, Menit, Detik */ .time-settings { display: flex; gap: 1rem; justify-content: center; align-items: center; margin: 1.5rem 0 1.8rem; flex-wrap: wrap; background: rgba(0, 0, 0, 0.2); padding: 1.2rem 1.5rem; border-radius: 40px; border: 1px solid rgba(255, 255, 255, 0.05); } .time-input-group { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; } .time-input-group label { font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.1em; color: #7a8db5; font-weight: 600; } .time-input-group input { width: 70px; padding: 0.5rem 0.3rem; text-align: center; font-size: 1.3rem; font-weight: 600; font-family: 'JetBrains Mono', monospace; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 16px; color: #e8eeff; outline: none; transition: all 0.2s; } .time-input-group input:focus { border-color: #6c8cff; background: rgba(108, 140, 255, 0.08); box-shadow: 0 0 20px rgba(108, 140, 255, 0.1); } .time-input-group input::-webkit-inner-spin-button, .time-input-group input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } .time-input-group input[type="number"] { -moz-appearance: textfield; } .time-separator { font-size: 2rem; font-weight: 300; color: #4a5a7a; padding-bottom: 0.5rem; align-self: flex-end; } .btn-apply { padding: 0.6rem 1.8rem; border: none; border-radius: 40px; background: linear-gradient(135deg, #4c6ef5, #7c5cfc); color: white; font-weight: 600; font-size: 0.9rem; cursor: pointer; transition: all 0.2s; box-shadow: 0 4px 16px rgba(76, 110, 245, 0.25); align-self: flex-end; margin-bottom: 0.1rem; } .btn-apply:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(76, 110, 245, 0.35); } .btn-apply:active { transform: scale(0.95); } /* Control Buttons */ .controls { display: flex; gap: 0.8rem; justify-content: center; flex-wrap: wrap; margin: 1.8rem 0 1.5rem; } .btn { display: inline-flex; align-items: center; gap: 0.6rem; padding: 0.8rem 1.8rem; border: none; border-radius: 60px; font-size: 0.95rem; font-weight: 600; cursor: pointer; transition: all 0.2s ease; background: rgba(255, 255, 255, 0.05); color: #bccbff; border: 1px solid rgba(255, 255, 255, 0.08); backdrop-filter: blur(4px); min-width: 110px; justify-content: center; } .btn i { font-size: 1rem; } .btn-primary { background: linear-gradient(135deg, #4c6ef5, #7c5cfc); color: white; border: none; box-shadow: 0 8px 24px rgba(76, 110, 245, 0.25); } .btn-primary:hover { transform: translateY(-2px); box-shadow: 0 12px 32px rgba(76, 110, 245, 0.35); } .btn-primary:active { transform: scale(0.95); } .btn-secondary { background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.1); } .btn-secondary:hover { background: rgba(255, 255, 255, 0.12); transform: translateY(-2px); } .btn-danger { background: rgba(239, 68, 68, 0.15); border: 1px solid rgba(239, 68, 68, 0.25); color: #fca5a5; } .btn-danger:hover { background: rgba(239, 68, 68, 0.25); transform: translateY(-2px); } .btn:disabled { opacity: 0.4; cursor: not-allowed; transform: none !important; } /* Presets */ .presets { display: flex; gap: 0.6rem; justify-content: center; flex-wrap: wrap; margin-top: 0.5rem; } .preset-btn { padding: 0.4rem 1.2rem; border-radius: 40px; border: 1px solid rgba(255, 255, 255, 0.06); background: rgba(255, 255, 255, 0.03); color: #8b9fc9; font-size: 0.8rem; font-weight: 500; cursor: pointer; transition: all 0.2s; font-family: inherit; } .preset-btn:hover { background: rgba(108, 140, 255, 0.12); border-color: rgba(108, 140, 255, 0.25); color: #d6e2ff; transform: translateY(-1px); } .preset-btn.active { background: rgba(108, 140, 255, 0.15); border-color: #4c6ef5; color: #fff; } /* Status */ .status { display: flex; align-items: center; justify-content: center; gap: 0.6rem; margin-top: 1.8rem; padding-top: 1.2rem; border-top: 1px solid rgba(255, 255, 255, 0.04); color: #6a7fa8; font-size: 0.85rem; } .status i { font-size: 0.8rem; } .status-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; transition: background 0.3s; } .status-dot.idle { background: #6a7fa8; } .status-dot.running { background: #4ade80; box-shadow: 0 0 12px rgba(74, 222, 128, 0.4); animation: pulse-dot 1.2s infinite; } .status-dot.paused { background: #fbbf24; box-shadow: 0 0 12px rgba(251, 191, 36, 0.3); } .status-dot.finished { background: #f87171; box-shadow: 0 0 12px rgba(248, 113, 113, 0.3); } @keyframes pulse-dot { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.6; transform: scale(0.85); } } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.08); color: #ff8a8a; } 100% { transform: scale(1); } } /* Responsive */ @media (max-width: 650px) { .card { padding: 1.8rem 1.5rem 2rem; border-radius: 40px; } .timer-numbers { font-size: 3.8rem; } .time-settings { padding: 1rem; gap: 0.5rem; } .time-input-group input { width: 55px; font-size: 1.1rem; padding: 0.4rem 0.2rem; } .time-separator { font-size: 1.5rem; } .btn-apply { padding: 0.5rem 1.2rem; font-size: 0.8rem; } .header-left h1 { font-size: 1.2rem; } .header-left i { font-size: 1.4rem; padding: 0.5rem; } .btn { padding: 0.7rem 1.2rem; font-size: 0.85rem; min-width: 90px; } } @media (max-width: 450px) { .timer-numbers { font-size: 2.8rem; } .time-settings { flex-wrap: wrap; justify-content: center; } .time-input-group input { width: 50px; font-size: 1rem; } .time-separator { display: none; } .controls { gap: 0.5rem; } .btn { padding: 0.6rem 1rem; font-size: 0.8rem; min-width: 70px; } .preset-btn { font-size: 0.7rem; padding: 0.3rem 0.8rem; } } </style> </head> <body> <div class="card"> <!-- Header --> <div class="header"> <div class="header-left"> <i class="fas fa-clock"></i> <h1>Count<span>down</span></h1> </div> <span class="badge">⏱️ setting waktu</span> </div> <!-- Timer Display --> <div class="timer-display"> <div class="timer-numbers" id="timerDisplay">00:05:00</div> <div class="timer-label">Waktu tersisa</div> <div class="timer-progress"> <div class="timer-progress-bar" id="progressBar" style="width: 100%"></div> </div> </div> <!-- Setting Waktu: Jam, Menit, Detik --> <div class="time-settings"> <div class="time-input-group"> <label for="inputJam">Jam</label> <input type="number" id="inputJam" min="0" max="99" value="0"> </div> <span class="time-separator">:</span> <div class="time-input-group"> <label for="inputMenit">Menit</label> <input type="number" id="inputMenit" min="0" max="59" value="5"> </div> <span class="time-separator">:</span> <div class="time-input-group"> <label for="inputDetik">Detik</label> <input type="number" id="inputDetik" min="0" max="59" value="0"> </div> <button class="btn-apply" id="applyTimeBtn"> <i class="fas fa-check"></i> Terapkan </button> </div> <!-- Controls --> <div class="controls"> <button class="btn btn-primary" id="startBtn"> <i class="fas fa-play"></i> Mulai </button> <button class="btn btn-secondary" id="pauseBtn" disabled> <i class="fas fa-pause"></i> Jeda </button> <button class="btn btn-secondary" id="resumeBtn" disabled> <i class="fas fa-play"></i> Lanjut </button> <button class="btn btn-danger" id="resetBtn"> <i class="fas fa-undo"></i> Reset </button> </div> <!-- Presets --> <div class="presets"> <button class="preset-btn" data-hours="0" data-minutes="1" data-seconds="0">1 menit</button> <button class="preset-btn active" data-hours="0" data-minutes="5" data-seconds="0">5 menit</button> <button class="preset-btn" data-hours="0" data-minutes="10" data-seconds="0">10 menit</button> <button class="preset-btn" data-hours="0" data-minutes="30" data-seconds="0">30 menit</button> <button class="preset-btn" data-hours="1" data-minutes="0" data-seconds="0">1 jam</button> <button class="preset-btn" data-hours="2" data-minutes="0" data-seconds="0">2 jam</button> </div> <!-- Status --> <div class="status"> <span class="status-dot idle" id="statusDot"></span> <span id="statusText">Siap</span> <span style="margin-left: 0.5rem; opacity: 0.4;">|</span> <span id="timeElapsed" style="opacity: 0.6;">00:00:00</span> </div> </div> <!-- Font Awesome --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> <script> (function() { 'use strict'; // DOM Elements const timerDisplay = document.getElementById('timerDisplay'); const progressBar = document.getElementById('progressBar'); const startBtn = document.getElementById('startBtn'); const pauseBtn = document.getElementById('pauseBtn'); const resumeBtn = document.getElementById('resumeBtn'); const resetBtn = document.getElementById('resetBtn'); const statusDot = document.getElementById('statusDot'); const statusText = document.getElementById('statusText'); const timeElapsed = document.getElementById('timeElapsed'); const presetBtns = document.querySelectorAll('.preset-btn'); const inputJam = document.getElementById('inputJam'); const inputMenit = document.getElementById('inputMenit'); const inputDetik = document.getElementById('inputDetik'); const applyTimeBtn = document.getElementById('applyTimeBtn'); // State let totalSeconds = 300; // 5 menit default let remainingSeconds = totalSeconds; let elapsedSeconds = 0; let timerInterval = null; let isRunning = false; let isPaused = false; let isFinished = false; // Format waktu HH:MM:SS function formatTime(seconds) { const hrs = Math.floor(seconds / 3600); const mins = Math.floor((seconds % 3600) / 60); const secs = seconds % 60; return `${String(hrs).padStart(2, '0')}:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`; } // Update tampilan timer & progress function updateDisplay() { timerDisplay.textContent = formatTime(remainingSeconds); const progress = totalSeconds > 0 ? (remainingSeconds / totalSeconds) * 100 : 0; progressBar.style.width = `${Math.max(0, progress)}%`; // Update elapsed time const elapsed = totalSeconds - remainingSeconds; timeElapsed.textContent = formatTime(Math.max(0, elapsed)); } // Update status dot & text function updateStatus(state, msg) { statusDot.className = 'status-dot'; if (state === 'idle') { statusDot.classList.add('idle'); statusText.textContent = msg || 'Siap'; } else if (state === 'running') { statusDot.classList.add('running'); statusText.textContent = msg || 'Berjalan...'; } else if (state === 'paused') { statusDot.classList.add('paused'); statusText.textContent = msg || 'Dijeda'; } else if (state === 'finished') { statusDot.classList.add('finished'); statusText.textContent = msg || 'Selesai!'; } } // Hentikan interval function stopTimer() { if (timerInterval) { clearInterval(timerInterval); timerInterval = null; } isRunning = false; isPaused = false; } // Mulai timer (internal) function startTimerInternal() { if (timerInterval) return; if (remainingSeconds <= 0) { resetTimer(); return; } isRunning = true; isPaused = false; isFinished = false; updateStatus('running', 'Berjalan...'); // Update button states startBtn.disabled = true; pauseBtn.disabled = false; resumeBtn.disabled = true; resetBtn.disabled = false; timerInterval = setInterval(() => { if (remainingSeconds > 0) { remainingSeconds--; elapsedSeconds++; updateDisplay(); // Cek jika waktu habis if (remainingSeconds === 0) { stopTimer(); isFinished = true; updateStatus('finished', '⏰ Waktu habis!'); startBtn.disabled = false; pauseBtn.disabled = true; resumeBtn.disabled = true; // Trigger animasi timerDisplay.style.animation = 'none'; setTimeout(() => { timerDisplay.style.animation = 'pulse 0.6s ease 3'; }, 10); // Play sound effect via Web Audio try { const ctx = new (window.AudioContext || window.webkitAudioContext)(); const osc = ctx.createOscillator(); const gain = ctx.createGain(); osc.connect(gain); gain.connect(ctx.destination); osc.frequency.value = 880; gain.gain.value = 0.15; osc.start(); osc.stop(ctx.currentTime + 0.3); } catch(e) { /* silent fallback */ } } } }, 1000); } // Jeda timer function pauseTimer() { if (!isRunning || isPaused) return; stopTimer(); isPaused = true; updateStatus('paused', 'Dijeda'); startBtn.disabled = true; pauseBtn.disabled = true; resumeBtn.disabled = false; resetBtn.disabled = false; } // Lanjutkan timer function resumeTimer() { if (!isPaused || isFinished) return; if (remainingSeconds <= 0) { resetTimer(); return; } startTimerInternal(); pauseBtn.disabled = false; resumeBtn.disabled = true; startBtn.disabled = true; } // Reset timer function resetTimer() { stopTimer(); isRunning = false; isPaused = false; isFinished = false; remainingSeconds = totalSeconds; elapsedSeconds = 0; updateDisplay(); updateStatus('idle', 'Siap'); startBtn.disabled = false; pauseBtn.disabled = true; resumeBtn.disabled = true; resetBtn.disabled = false; progressBar.style.width = '100%'; // Update input fields sesuai totalSeconds const hrs = Math.floor(totalSeconds / 3600); const mins = Math.floor((totalSeconds % 3600) / 60); const secs = totalSeconds % 60; inputJam.value = hrs; inputMenit.value = mins; inputDetik.value = secs; } // Set waktu baru dari jam, menit, detik function setTimeFromInputs() { if (isRunning) { stopTimer(); } let jam = parseInt(inputJam.value) || 0; let menit = parseInt(inputMenit.value) || 0; let detik = parseInt(inputDetik.value) || 0; // Validasi jam = Math.max(0, jam); menit = Math.max(0, Math.min(59, menit)); detik = Math.max(0, Math.min(59, detik)); totalSeconds = (jam * 3600) + (menit * 60) + detik; if (totalSeconds === 0) { totalSeconds = 1; // Minimal 1 detik inputDetik.value = 1; } remainingSeconds = totalSeconds; elapsedSeconds = 0; isRunning = false; isPaused = false; isFinished = false; updateDisplay(); updateStatus('idle', 'Siap'); startBtn.disabled = false; pauseBtn.disabled = true; resumeBtn.disabled = true; resetBtn.disabled = false; // Update preset aktif presetBtns.forEach(btn => { const h = parseInt(btn.dataset.hours) || 0; const m = parseInt(btn.dataset.minutes) || 0; const s = parseInt(btn.dataset.seconds) || 0; const presetTotal = (h * 3600) + (m * 60) + s; btn.classList.toggle('active', presetTotal === totalSeconds); }); } // Set waktu dari preset function setTimeFromPreset(hours, minutes, seconds) { const jam = parseInt(hours) || 0; const menit = parseInt(minutes) || 0; const detik = parseInt(seconds) || 0; inputJam.value = jam; inputMenit.value = menit; inputDetik.value = detik; setTimeFromInputs(); } // --- Event Listeners --- startBtn.addEventListener('click', startTimerInternal); pauseBtn.addEventListener('click', pauseTimer); resumeBtn.addEventListener('click', resumeTimer); resetBtn.addEventListener('click', resetTimer); applyTimeBtn.addEventListener('click', setTimeFromInputs); // Preset buttons presetBtns.forEach(btn => { btn.addEventListener('click', function(e) { const hours = this.dataset.hours || 0; const minutes = this.dataset.minutes || 0; const seconds = this.dataset.seconds || 0; setTimeFromPreset(hours, minutes, seconds); }); }); // Keyboard shortcuts (spasi untuk start/pause) document.addEventListener('keydown', function(e) { if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return; if (e.code === 'Space') { e.preventDefault(); if (isRunning && !isPaused) { pauseTimer(); } else if (isPaused && !isFinished) { resumeTimer(); } else if (!isRunning && !isPaused && !isFinished) { startTimerInternal(); } } if (e.code === 'KeyR') { resetTimer(); } }); // Enter pada input untuk apply [inputJam, inputMenit, inputDetik].forEach(input => { input.addEventListener('keydown', function(e) { if (e.key === 'Enter') { setTimeFromInputs(); } }); }); // Inisialisasi resetTimer(); console.log('⏱️ Countdown Timer siap! Shortcut: Spasi (start/pause), R (reset)'); console.log('💡 Atur waktu di kolom Jam, Menit, Detik lalu klik "Terapkan"'); })(); </script> </body> </html>

Berdasarkan Fungsi countdown timer terbagi menjadi 2 yaitu Fixed Timer Timer dapat berjalan sampai batas waktu tertentudan Dynamic Timer dimana timer dihitung berdasarkan pengguna misalnya sejak login atau sejak mulai mengerjakan ujian. Untuk anda yang ingin menggunakan timer tanpa instalasi dan download countdown timer tanpa ribet mudah digunakan dan bisa online countdown timer full screen dimana saya anda bisa mencoba pada halaman countdown timer yang dibuat pada blog ini yang online countdown timer dan bisa full screen di https://panduanform.blogspot.com/p/countdown-timer.html
OlderNewest

Post a Comment

Silahkan berkomentar dengan baik dan benar