document.addEventListener('DOMContentLoaded', () => { // --- GLOBALS --- const qrContainer = document.getElementById('qr-container'); const downloadBtn = document.getElementById('btn-download'); // Inputs const modeSelector = document.getElementById('mode-selector'); const optEcc = document.getElementById('opt-ecc'); const optSize = document.getElementById('opt-size'); const optFg = document.getElementById('opt-fg'); const optBg = document.getElementById('opt-bg'); // Hex Labels (for display) const hexFg = document.getElementById('hex-fg'); const hexBg = document.getElementById('hex-bg'); let qrcodeObj = null; let debounceTimer; // --- LOGIC --- function createQRInstance() { qrContainer.innerHTML = ''; // Validation: Clamp size to prevent crashing browser let size = parseInt(optSize.value); if (isNaN(size) || size < 64) size = 64; if (size > 4000) size = 4000; const ecc = QRCode.CorrectLevel[optEcc.value]; const colorDark = optFg.value; const colorLight = optBg.value; // Update Hex Labels hexFg.textContent = colorDark; hexBg.textContent = colorLight; qrcodeObj = new QRCode(qrContainer, { width: size, height: size, colorDark : colorDark, colorLight : colorLight, correctLevel : ecc }); updateQR(); } function getDataString() { const mode = modeSelector.value; if (mode === 'text') { return document.getElementById('inp-text').value; } else if (mode === 'wifi') { const ssid = document.getElementById('inp-wifi-ssid').value; const pass = document.getElementById('inp-wifi-pass').value; const type = document.getElementById('inp-wifi-type').value; if (!ssid) return ''; const cleanSSID = ssid.replace(/([\\;,:])/g, '\\$1'); const cleanPass = pass.replace(/([\\;,:])/g, '\\$1'); return `WIFI:S:${cleanSSID};T:${type};P:${cleanPass};;`; } else if (mode === 'email') { const to = document.getElementById('inp-email-to').value; const sub = document.getElementById('inp-email-sub').value; const body = document.getElementById('inp-email-body').value; if (!to) return ''; return `mailto:${to}?subject=${encodeURIComponent(sub)}&body=${encodeURIComponent(body)}`; } return ''; } function updateQR() { if (!qrcodeObj) return; const data = getDataString(); if (!data || data.trim() === '') { qrcodeObj.clear(); downloadBtn.disabled = true; return; } downloadBtn.disabled = false; qrcodeObj.makeCode(data); } // --- EVENT LISTENERS --- // 1. Config Changes (Re-create instance) // We listen to 'change' for colors (happens when picker closes) // and 'input' (happens while dragging) depending on preference. // 'input' is smoother but more CPU intensive. Let's use 'input'. [optEcc, optSize, optFg, optBg].forEach(el => { el.addEventListener('input', () => { // Debounce the recreation slightly to prevent lag during color dragging clearTimeout(debounceTimer); debounceTimer = setTimeout(createQRInstance, 100); }); }); // 2. Mode Switching modeSelector.addEventListener('change', (e) => { const newMode = e.target.value; document.querySelectorAll('.input-form').forEach(f => f.classList.remove('active')); document.getElementById(`form-${newMode}`).classList.add('active'); updateQR(); }); // 3. Data Entry (Text, WiFi, Email) document.querySelectorAll('.input-form').forEach(form => { form.addEventListener('input', () => { clearTimeout(debounceTimer); debounceTimer = setTimeout(updateQR, 300); }); }); // 4. Download downloadBtn.addEventListener('click', () => { const img = qrContainer.querySelector('img'); if (img && img.src) { const link = document.createElement('a'); link.href = img.src; link.download = `qrcode-${Date.now()}.png`; document.body.appendChild(link); link.click(); document.body.removeChild(link); } }); // Init createQRInstance(); });