Aplikasi Jam Digital Masjid Gratis -

<!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"> <title>Jam Digital Masjid | Waktu Salat & Pengingat Azan</title> <style> * margin: 0; padding: 0; box-sizing: border-box; user-select: none; /* hindari seleksi teks pada jam */ body background: linear-gradient(145deg, #0a2f2a 0%, #031010 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; font-family: 'Segoe UI', 'Poppins', 'Tahoma', system-ui, -apple-system, 'Roboto', sans-serif; padding: 20px;

// Render jadwal sholat di grid, highlight selanjutnya function renderPrayerTimes(now) if (!prayerGrid) return; prayerGrid.innerHTML = ""; let nowMinutes = now.getHours() * 60 + now.getMinutes(); let nextIdx = -1; let smallestDiff = Infinity; // menentukan sholat berikutnya for (let i = 0; i < prayerNamesOrder.length; i++) const nama = prayerNamesOrder[i]; let waktuStr = prayerSchedule[nama]; if (!waktuStr) continue; let [jam, menit] = waktuStr.split(":").map(Number); let totalMenit = jam * 60 + menit; let diff = totalMenit - nowMinutes; if (diff < 0) diff += 24*60; if (diff < smallestDiff) smallestDiff = diff; nextIdx = i; for (let i = 0; i < prayerNamesOrder.length; i++) nextPrayerIndex = nextIdx;

// inisialisasi + update setiap detik let intervalId; function initApp() getLocationAndUpdate(); // coba ambil data jadwal // update jam tiap 1 detik intervalId = setInterval(() => updateClockAndDate(); , 1000); updateClockAndDate(); testBtn.addEventListener('click', () => stopAzanSound(); triggerAzan("Demo Azan"); ); resetBtn.addEventListener('click', () => stopAzanSound(); azanMsgSpan.classList.remove('azan-active'); azanMsgSpan.innerText = "🔇 Suara dihentikan manual"; setTimeout(() => updateAzanMessageDefault(), 2000); );

/* area jam digital LED */ .jam-led background: #0a0f0e; border-radius: 48px; padding: 25px 15px; text-align: center; box-shadow: inset 0 0 12px #00b89433, 0 10px 20px rgba(0,0,0,0.3); border: 1px solid #2e7d64; aplikasi jam digital masjid gratis

.city-name font-size: 1.2rem; background: #d4af37; color: #1e2f2c; padding: 4px 14px; border-radius: 40px; font-weight: bold;

.hijri-date font-size: 0.95rem; background: #2c5a50; padding: 4px 12px; border-radius: 30px; color: #f9eec1;

.footer-note text-align: center; font-size: 0.7rem; color: #bbbb88; margin-top: 20px; Tanggal Hijriah dari API atau fallback lokal

.prayer-card background: linear-gradient(135deg, #1f3b35, #102622); border-radius: 32px; text-align: center; padding: 12px 5px; transition: all 0.2s ease; border: 1px solid #2f8b72; box-shadow: 0 4px 6px #00000030;

<!-- jadwal sholat otomatis --> <div class="prayer-times" id="prayerGrid"> <!-- diisi js --> </div>

@keyframes pulse 0% opacity: 0.7; text-shadow: 0 0 0px gold; 100% opacity: 1; text-shadow: 0 0 6px #ffaa33; currentAudio = null

function updateAzanMessageDefault() if (!azanMsgSpan.innerText.includes("AZAN BERKUMANDANG")) azanMsgSpan.innerHTML = "🔔 Menunggu waktu salat berikutnya"; azanMsgSpan.classList.remove('azan-active');

<div class="azan-status" id="azanStatusArea"> <span class="alert-badge">🔊 Status Azan: </span> <span id="azanMessage" class="alert-badge">Menunggu waktu salat</span> </div> <div style="display: flex; justify-content: center; gap: 15px;"> <button id="testAzanBtn">🔔 Uji Coba Azan (Demo)</button> <button id="resetAzanBtn">🔇 Hentikan Suara</button> </div> <div class="footer-note"> ⏰ Waktu salat berdasarkan kota Jakarta (otomatis deteksi lokasi atau default) • Azan berupa notifikasi suara & visual </div> </div> </div>

<script> // ======================== FITUR JAM DIGITAL MASJID GRATIS ======================== // 1. Jam realtime dengan format HH:MM:SS // 2. Jadwal sholat otomatis (API atau fallback offline) + perhitungan sederhana // Menggunakan API gratis Aladhan untuk akurasi (jika online) + fallback manual. // 3. Deteksi waktu sholat berikutnya + highlight // 4. Azan suara (menggunakan Web Audio / synth sederhana, tanpa file eksternal) // 5. Tanggal Hijriah dari API atau fallback lokal. // 6. Mode responsif, tampilan LED dan nuansa masjid. // ------------------------------------------------------------------------------

.prayer-time font-size: 1.6rem; font-family: monospace; font-weight: 700; color: #f0f3f5; margin-top: 6px;

// Fungsi untuk memutar suara azan (menggunakan oscillator sederhana, mirip nada panjang) function playAzanSound() // Hentikan audio sebelumnya jika ada if (currentAudio) currentAudio.pause(); currentAudio = null; // Menggunakan AudioContext (web audio) untuk suara azan sederhana try window.webkitAudioContext; const audioCtx = new AudioContextClass(); currentAudio = audioCtx; let startTime = audioCtx.currentTime; // nada azan sederhana: rangkaian frekuensi dan durasi (simulasi panggilan) const notes = [ freq: 440, dur: 0.8 , // A freq: 494, dur: 0.8 , // B freq: 523, dur: 1.0 , // C freq: 587, dur: 0.9 , // D freq: 523, dur: 0.8 , freq: 440, dur: 1.2 , freq: 659, dur: 1.0 , // E freq: 587, dur: 1.2 , freq: 523, dur: 1.5 ]; let timeCursor = startTime; for (let note of notes) const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.connect(gain); gain.connect(audioCtx.destination); osc.frequency.value = note.freq; gain.gain.value = 0.35; osc.start(timeCursor); gain.gain.exponentialRampToValueAtTime(0.0001, timeCursor + note.dur); osc.stop(timeCursor + note.dur); timeCursor += note.dur; // tambah nafas panjang const finalOsc = audioCtx.createOscillator(); const finalGain = audioCtx.createGain(); finalOsc.connect(finalGain); finalGain.connect(audioCtx.destination); finalOsc.frequency.value = 440; finalGain.gain.value = 0.3; finalOsc.start(timeCursor); finalGain.gain.exponentialRampToValueAtTime(0.0001, timeCursor + 2.2); finalOsc.stop(timeCursor + 2.2); // resume jika suspended if (audioCtx.state === 'suspended') audioCtx.resume(); // status selesai cleanup setTimeout(() => if (currentAudio === audioCtx) currentAudio = null; , (timeCursor + 2.5) * 1000); catch(e) console.warn("AudioContext error:", e); azanMsgSpan.innerText = "⚠️ Browser tidak support audio, azan visual tetap aktif.";