- Mesajlar
- 1,785
Zil Programı v1.0 Alfa Test Sürümü (Offline HTML)
HTML tabanlı bir zil programıdır.
Tüm işletim sistemlerinde çalışır.
Kurulum gerekmez – Sadece tarayıcınızda açmanız yeterlidir.
İnternet bağlantısı gerekmez – Tüm ayarlar ve sesler tarayıcıda saklanır.
Her güne özel ders programı oluşturabilir, öğrenci, öğretmen ve teneffüs zilleri atayabilirsiniz.
Kendi MP3 veya WAV ses dosyalarınızı yükleyip zilleri özelleştirebilirsiniz.
Saygı Duruşu ve İstiklal Marşı tek tuşla çalınabilir.
Ayarlarınızı dışa aktarabilir (yedekleyebilir) ve aynı cihazda veya başka cihazlarda içe aktarabilirsiniz (yedekten geri yükleyebilirsiniz).
*.html dosyası ile aynı dizinde ayarlar.json dosyası varsa o dosyadaki ayarları yükler yoksa varsayılan ayarlarla açılır.
*.html kodları aşağıda paylaşılmıştır.
Ses dosyaları ekli değildir. İlgili sesleri aşağıdaki bağlantılardan indirip programa ekleyebilirsiniz.
LocalStorage sınırlamaları nedeniyle ses dosyalarının toplam boyutunun 4 MB’ı geçmemesi önerilir.
Ses Dosyaları: https://erzin.meb.gov.tr/www/ornek-okul-zil-sesleri/icerik/1140
HTML tabanlı bir zil programıdır.
Tüm işletim sistemlerinde çalışır.
Kurulum gerekmez – Sadece tarayıcınızda açmanız yeterlidir.
İnternet bağlantısı gerekmez – Tüm ayarlar ve sesler tarayıcıda saklanır.
Her güne özel ders programı oluşturabilir, öğrenci, öğretmen ve teneffüs zilleri atayabilirsiniz.
Kendi MP3 veya WAV ses dosyalarınızı yükleyip zilleri özelleştirebilirsiniz.
Saygı Duruşu ve İstiklal Marşı tek tuşla çalınabilir.
Ayarlarınızı dışa aktarabilir (yedekleyebilir) ve aynı cihazda veya başka cihazlarda içe aktarabilirsiniz (yedekten geri yükleyebilirsiniz).
*.html dosyası ile aynı dizinde ayarlar.json dosyası varsa o dosyadaki ayarları yükler yoksa varsayılan ayarlarla açılır.
*.html kodları aşağıda paylaşılmıştır.
Ses dosyaları ekli değildir. İlgili sesleri aşağıdaki bağlantılardan indirip programa ekleyebilirsiniz.
LocalStorage sınırlamaları nedeniyle ses dosyalarının toplam boyutunun 4 MB’ı geçmemesi önerilir.
Ses Dosyaları: https://erzin.meb.gov.tr/www/ornek-okul-zil-sesleri/icerik/1140
Kod:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zil Programı v1.0 Alfa</title>
<style>
body { font-family: Arial; background: #f8f9fa; color: #333; text-align: center; margin:0; padding:0; min-height:100vh; display:flex; flex-direction:column; }
h1 { background: #007bff; color: white; padding: 10px; margin:0; }
.gun-secimi { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 20px 0; }
.gun-secimi label { margin: 0; font-weight: bold; }
#gunSec { padding: 8px 12px; font-size: 16px; border-radius: 5px; border: 1px solid #007bff; background-color: white; color: #007bff; display: block; }
table { margin: 0 auto 20px auto; border-collapse: collapse; width: 95%; max-width: 900px; }
th, td { border: 1px solid #ccc; padding: 8px; text-align: center; }
th { background: #007bff; color: white; }
input[type="time"], input[type="text"] { padding: 5px; }
.aktif { background-color: #d4edda !important; transition: background 0.5s; }
select, button { margin: 5px; padding: 10px; cursor: pointer; }
#durum { font-weight: bold; color: #007bff; margin-top: 10px; }
.kontroller { margin-top:10px; display:flex; justify-content:center; flex-wrap:wrap; gap:5px; }
.stop-btn { background-color: #dc3545; color: white; border: none; padding: 10px 20px; }
.stop-btn:hover { background-color: #c82333; }
.zil-secici { display: none; margin: 10px auto; width: fit-content; border: 1px solid #ccc; padding: 10px; border-radius: 8px; background: #fff; text-align:left; }
.zil-dosya-grid { display: grid; grid-template-columns: 150px 150px 1fr; gap: 8px 10px; align-items: center; margin-bottom: 10px; }
.zil-dosya-grid label { text-align: left; padding-left: 5px; width: 150px; display: inline-block; }
.zil-dosya-grid span { display: inline-block; }
.zil-dosya-grid input[type="file"] { padding: 2px; }
.zil-panel-btnlar { margin-top: 10px; display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; }
footer { margin-top:auto; background:#f1f1f1; padding:10px 0; font-size:14px; color:#555; }
</style>
</head>
<body>
<h1>📢 Zil Programı v1.0 Alfa</h1>
<div class="gun-secimi">
<label for="gunSec">Gün Seçimi:</label>
<select id="gunSec"></select>
</div>
<table id="zilTablosu">
<tr>
<th>Ders / Etkinlik</th>
<th>Öğrenci Zili</th>
<th>Öğretmen Zili</th>
<th>Teneffüs Zili</th>
</tr>
</table>
<div class="kontroller">
<button onclick="zilCal('ogrenci', tablo.rows[1], 'Öğrenci Zili')">🔔 Öğrenci Zili</button>
<button onclick="zilCal('ogretmen', tablo.rows[1], 'Öğretmen Zili')">🔔 Öğretmen Zili</button>
<button onclick="zilCal('bitis', tablo.rows[1], 'Teneffüs Zili')">🔔 Teneffüs Zili</button>
<button onclick="zilCal('siren', tablo.rows[1], 'Siren')">🚨 Siren</button>
<button onclick="saygiDurusu()">🕊️ Saygı Duruşu</button>
<button onclick="istiklalMars()">🎵 İstiklal Marşı</button>
<button onclick="saygiVeMars()">🇹🇷 Saygı Duruşu ve İstiklal Marşı</button>
<button class="stop-btn" onclick="durdur()">⏹️ Durdur</button>
<button onclick="toggleAyarlar()">⚙️ Zil Ayarları</button>
</div>
<p id="durum"></p>
<audio id="zilSes" preload="auto"></audio>
<audio id="marsSes" preload="auto"></audio>
<audio id="saygiSes" preload="auto"></audio>
<audio id="saygiMarsSes" preload="auto"></audio>
<div class="zil-secici" id="zilAyarlar">
<h3>🔈 Zil Sesleri Seçimi</h3>
<div class="zil-dosya-grid">
<label>Öğrenci Zili:</label><span id="ogrenciDosya">Dosya seçilmedi</span><input type="file" id="ogrenciZil" accept="audio/*">
<label>Öğretmen Zili:</label><span id="ogretmenDosya">Dosya seçilmedi</span><input type="file" id="ogretmenZil" accept="audio/*">
<label>Teneffüs Zili:</label><span id="bitisDosya">Dosya seçilmedi</span><input type="file" id="bitisZil" accept="audio/*">
<label>Siren:</label><span id="sirenDosya">Dosya seçilmedi</span><input type="file" id="sirenZil" accept="audio/*">
<label>Saygı Duruşu:</label><span id="saygiDosya">Dosya seçilmedi</span><input type="file" id="saygiZil" accept="audio/*">
<label>İstiklal Marşı:</label><span id="marsDosya">Dosya seçilmedi</span><input type="file" id="marsZil" accept="audio/*">
<label>Saygı Duruşu ve İstiklal Marşı:</label><span id="saygiMarsDosya">Dosya seçilmedi</span><input type="file" id="saygiMarsZil" accept="audio/*">
</div>
<div class="zil-panel-btnlar">
<button onclick="satirEkle()">➕ Satır Ekle</button>
<button onclick="satirSil()">➖ Satır Sil</button>
<button onclick="kaydet()">💾 Kaydet</button>
<button onclick="disariAktar()">📤 Dışarı Aktar</button>
<button onclick="iceriAktar()">📥 İçeri Aktar</button>
</div>
</div>
<footer>© Mehmet TOKTAŞ | 2025</footer>
<script>
const tablo = document.getElementById("zilTablosu");
const gunSec = document.getElementById("gunSec");
const durum = document.getElementById("durum");
const zilSes = document.getElementById("zilSes");
const marsSes = document.getElementById("marsSes");
const saygiSes = document.getElementById("saygiSes");
const saygiMarsSes = document.getElementById("saygiMarsSes");
const zilAyarlar = document.getElementById("zilAyarlar");
let sesler = { ogrenci:null, ogretmen:null, bitis:null, saygi:null, mars:null, siren:null, saygiMars:null };
const ogeler = {
ogrenciZil:["ogrenciDosya","ogrenci"],
ogretmenZil:["ogretmenDosya","ogretmen"],
bitisZil:["bitisDosya","bitis"],
saygiZil:["saygiDosya","saygi"],
marsZil:["marsDosya","mars"],
sirenZil:["sirenDosya","siren"],
saygiMarsZil:["saygiMarsDosya","saygiMars"]
};
const gunler = ["Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi","Pazar"];
gunler.forEach(g => gunSec.add(new Option(g)));
const simdi = new Date();
gunSec.value = gunler[simdi.getDay() - 1] || "Pazartesi";
for (const [id,[etiket,tur]] of Object.entries(ogeler)) {
const input = document.getElementById(id);
const span = document.getElementById(etiket);
input.addEventListener("change", e => {
const dosya = e.target.files[0];
if (!dosya) {
span.textContent = "Dosya seçilmedi";
sesler[tur] = null;
localStorage.removeItem("v1_ses_"+tur);
localStorage.removeItem("v1_ses_"+tur+"_name");
return;
}
span.textContent = dosya.name.length > 25 ? dosya.name.slice(0,25) + "…" : dosya.name;
const reader = new FileReader();
reader.onload = () => {
sesler[tur] = reader.result;
localStorage.setItem("v1_ses_"+tur, reader.result);
localStorage.setItem("v1_ses_"+tur+"_name", dosya.name);
durum.textContent = `${tur} sesi kaydedildi 🔔`;
setTimeout(()=>durum.textContent="",3000);
};
reader.readAsDataURL(dosya);
});
const kayit = localStorage.getItem("v1_ses_"+tur);
const isim = localStorage.getItem("v1_ses_"+tur+"_name");
if (kayit && isim) {
sesler[tur] = kayit;
span.textContent = isim.length > 25 ? isim.slice(0,25) + "…" : isim;
} else {
span.textContent = "Dosya seçilmedi";
}
}
window.onload = () => {
zilAyarlar.style.display = "none";
tabloyuYukle();
otomatikYukle();
setInterval(kontrolEt, 500);
};
gunSec.addEventListener("change", tabloyuYukle);
function satirEkle(ad="", ogr="", ogrt="", bitis="") {
const s = tablo.insertRow();
s.insertCell(0).innerHTML = `<input type="text" value="${ad}" placeholder="Ders">`;
s.insertCell(1).innerHTML = `<input type="time" value="${ogr}">`;
s.insertCell(2).innerHTML = `<input type="time" value="${ogrt}">`;
s.insertCell(3).innerHTML = `<input type="time" value="${bitis}">`;
}
function satirSil() {
if (tablo.rows.length > 1) tablo.deleteRow(tablo.rows.length - 1);
}
function kaydet() {
const gun = gunSec.value;
const veriler = [];
for (let i = 1; i < tablo.rows.length; i++) {
const ad = tablo.rows[i].cells[0].querySelector("input").value;
const ogr = tablo.rows[i].cells[1].querySelector("input").value;
const ogrt = tablo.rows[i].cells[2].querySelector("input").value;
const bitis = tablo.rows[i].cells[3].querySelector("input").value;
if (ad) veriler.push({ad, ogr, ogrt, bitis});
}
localStorage.setItem("v1_zil_" + gun, JSON.stringify(veriler));
durum.textContent = gun + " programı kaydedildi ✅";
setTimeout(()=>durum.textContent="",3000);
}
function tabloyuYukle() {
while (tablo.rows.length > 1) tablo.deleteRow(1);
const gun = gunSec.value;
const kayit = localStorage.getItem("v1_zil_" + gun);
const veriler = kayit ? JSON.parse(kayit) : [];
if (veriler.length > 0) {
veriler.forEach(o => satirEkle(o.ad,o.ogr,o.ogrt,o.bitis));
} else {
const defaultSaatler = [["08:49","08:50","09:30"],["09:39","09:40","10:20"],["10:39","10:40","11:20"],["11:29","11:30","12:10"],["13:29","13:30","14:10"],["14:19","14:20","15:00"],["15:19","15:20","16:00"],["16:09","16:10","16:50"]];
if (["Pazartesi","Salı","Çarşamba","Perşembe","Cuma"].includes(gun)) {
for (let i = 0; i < defaultSaatler.length; i++) {
satirEkle(`${i+1}. Ders`, defaultSaatler[i][0], defaultSaatler[i][1], defaultSaatler[i][2]);
}
} else if (["Cumartesi","Pazar"].includes(gun)) {
for (let i = 0; i < 8; i++) { satirEkle(`${i+1}. Ders`, "", "", ""); }
}
}
}
function kontrolEt() {
const simdi = new Date();
const hhmm = simdi.toTimeString().slice(0,5);
for (let i=1;i<tablo.rows.length;i++){
const r = tablo.rows[i];
const ogr = r.cells[1].querySelector("input").value;
const ogrt = r.cells[2].querySelector("input").value;
const bitis = r.cells[3].querySelector("input").value;
if (ogr===hhmm) zilCal("ogrenci", r, "Öğrenci Zili");
if (ogrt===hhmm) zilCal("ogretmen", r, "Öğretmen Zili");
if (bitis===hhmm) zilCal("bitis", r, "Teneffüs Zili");
}
}
function zilCal(tur, satir, text) {
if (!sesler[tur]) return;
if(tur==="mars") { marsSes.src = sesler[tur]; marsSes.play(); }
else if(tur==="saygi") { saygiSes.src = sesler[tur]; saygiSes.play(); }
else if(tur==="saygiMars") { saygiMarsSes.src = sesler[tur]; saygiMarsSes.play(); }
else { zilSes.src = sesler[tur]; zilSes.play(); }
satir.classList.add("aktif");
setTimeout(()=>satir.classList.remove("aktif"), 5000);
durum.textContent = text + " çalıyor 🔔";
setTimeout(()=>durum.textContent="",3000);
}
function durdur() {
zilSes.pause(); zilSes.currentTime=0;
marsSes.pause(); marsSes.currentTime=0;
saygiSes.pause(); saygiSes.currentTime=0;
saygiMarsSes.pause(); saygiMarsSes.currentTime=0;
}
function saygiDurusu(){ if(sesler.saygi){ saygiSes.src = sesler.saygi; saygiSes.play(); durum.textContent="Saygı Duruşu ⏳"; setTimeout(()=>durum.textContent="",3000); } }
function istiklalMars(){ if(sesler.mars){ marsSes.src = sesler.mars; marsSes.play(); durum.textContent="İstiklal Marşı 🎵"; setTimeout(()=>durum.textContent="",3000); } }
function saygiVeMars(){
if(sesler.saygiMars){ saygiMarsSes.src = sesler.saygiMars; saygiMarsSes.play(); durum.textContent="Saygı Duruşu ve İstiklal Marşı ⏳"; setTimeout(()=>durum.textContent="",3000); }
else { saygiDurusu(); setTimeout(istiklalMars, 4000); }
}
function toggleAyarlar() { zilAyarlar.style.display = zilAyarlar.style.display==="none" ? "block" : "none"; }
function disariAktar() {
const program = {};
gunler.forEach(g=>{
const kayit = localStorage.getItem("v1_zil_"+g);
if(kayit) program[g]=JSON.parse(kayit);
});
const data={sesler, program};
const blob = new Blob([JSON.stringify(data,null,2)],{type:"application/json"});
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = "ayarlar.json";
a.click();
}
function iceriAktar() {
const input=document.createElement("input");
input.type="file";
input.accept=".json";
input.onchange=e=>{
const file=e.target.files[0];
if(!file) return;
const reader=new FileReader();
reader.onload=()=>{
try{
const data=JSON.parse(reader.result);
if(data.sesler){
for(const tur in data.sesler){
sesler[tur]=data.sesler[tur];
const span = document.getElementById(ogeler[tur+"Zil"]?[0]:null);
if(span) span.textContent = localStorage.getItem("v1_ses_"+tur+"_name") || "Dosya yüklü";
localStorage.setItem("v1_ses_"+tur,data.sesler[tur]);
}
}
if(data.program){
for(const g in data.program){
localStorage.setItem("v1_zil_"+g,JSON.stringify(data.program[g]));
}
}
tabloyuYukle();
durum.textContent="Ayarlar yüklendi ✅";
setTimeout(()=>durum.textContent="",3000);
}catch(e){ alert("Dosya okunamadı!"); }
};
reader.readAsText(file);
};
input.click();
}
function otomatikYukle() { tabloyuYukle(); }
</script>
</body>
</html>
Ekli dosyalar
Son düzenleme:


