import { hexToHsl, hslToHex, rgbToHsl, rgbToHex } from './converter.js'; const MAX_FARBEN = 4; const THUMB_SIZE = 120; // max px für Vorschaubild // Aktuell gesammelter Zustand des Modals let farben = []; // Array von HSL-Objekten let aktuelleHex = ''; // Hex-Wert des aktuellen Eingabefelds let vorschaubild = null; // Base64-String des Thumbnails oder null function compressToThumbnail(file) { return new Promise((resolve) => { const reader = new FileReader(); reader.onload = (e) => { const img = new Image(); img.onload = () => { const scale = Math.min(THUMB_SIZE / img.width, THUMB_SIZE / img.height, 1); const w = Math.round(img.width * scale); const h = Math.round(img.height * scale); const c = document.createElement('canvas'); c.width = w; c.height = h; c.getContext('2d').drawImage(img, 0, 0, w, h); resolve(c.toDataURL('image/jpeg', 0.8)); }; img.src = e.target.result; }; reader.readAsDataURL(file); }); } function resetModal() { farben = []; aktuelleHex = ''; vorschaubild = null; document.getElementById('schema-name-input').value = ''; document.getElementById('schema-hex-input').value = ''; document.getElementById('schema-hex-preview').style.background = '#eee'; document.getElementById('schema-farben-preview').textContent = ''; document.getElementById('schema-canvas').style.display = 'none'; document.getElementById('schema-canvas').getContext('2d').clearRect(0, 0, 1, 1); document.getElementById('schema-farbe-eingabe').style.display = 'block'; document.getElementById('schema-abschliessen-btn').disabled = true; // Vorschaubild-UI zurücksetzen const preview = document.getElementById('schema-bild-preview'); preview.style.backgroundImage = ''; preview.classList.remove('hat-bild'); document.getElementById('schema-bild-input').value = ''; document.getElementById('schema-bild-entfernen-btn').style.display = 'none'; updateFarbeLabel(); } function updateFarbeLabel() { document.getElementById('schema-farbe-label').textContent = 'Farbe ' + (farben.length + 1) + (farben.length === MAX_FARBEN - 1 ? ' (letzte)' : ''); } function renderFarbenPreview() { const container = document.getElementById('schema-farben-preview'); container.textContent = ''; farben.forEach((hsl, i) => { const hex = hslToHex(hsl); const cell = document.createElement('div'); cell.style.cssText = 'display:inline-flex;flex-direction:column;align-items:center;gap:0.2rem'; const swatch = document.createElement('div'); swatch.style.cssText = 'width:44px;height:44px;border-radius:6px;border:1px solid #ddd;background:' + hex; swatch.title = hex; const label = document.createElement('span'); label.style.cssText = 'font-size:0.7rem;font-family:monospace;color:#666'; label.textContent = hex; const removeBtn = document.createElement('button'); removeBtn.className = 'action-btn'; removeBtn.style.fontSize = '0.65rem'; removeBtn.textContent = '✕'; removeBtn.addEventListener('click', () => { farben.splice(i, 1); renderFarbenPreview(); updateFarbeLabel(); document.getElementById('schema-farbe-eingabe').style.display = 'block'; document.getElementById('schema-abschliessen-btn').disabled = farben.length === 0; }); cell.appendChild(swatch); cell.appendChild(label); cell.appendChild(removeBtn); container.appendChild(cell); }); } function loadImageOnCanvas(file) { const reader = new FileReader(); reader.onload = (e) => { const img = new Image(); img.onload = () => { const canvas = document.getElementById('schema-canvas'); canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); canvas.style.display = 'block'; // Mittlerer Pixel als Vorschlag const px = ctx.getImageData(Math.floor(img.width / 2), Math.floor(img.height / 2), 1, 1).data; setAktuelleHex(rgbToHex({ r: px[0], g: px[1], b: px[2] })); canvas.onclick = (ev) => { const rect = canvas.getBoundingClientRect(); const x = Math.floor((ev.clientX - rect.left) * canvas.width / rect.width); const y = Math.floor((ev.clientY - rect.top) * canvas.height / rect.height); const d = ctx.getImageData(x, y, 1, 1).data; setAktuelleHex(rgbToHex({ r: d[0], g: d[1], b: d[2] })); }; }; img.src = e.target.result; }; reader.readAsDataURL(file); } function setAktuelleHex(hex) { aktuelleHex = hex; document.getElementById('schema-hex-input').value = hex; document.getElementById('schema-hex-preview').style.background = hex; } export function initSchemaModal(onSave) { // Button öffnet Modal document.getElementById('schema-erstellen-btn').addEventListener('click', () => { resetModal(); document.getElementById('schema-modal-overlay').style.display = 'flex'; document.getElementById('schema-name-input').focus(); }); // Abbrechen document.getElementById('schema-abbrechen-btn').addEventListener('click', () => { document.getElementById('schema-modal-overlay').style.display = 'none'; }); // Klick außerhalb schließt Modal document.getElementById('schema-modal-overlay').addEventListener('click', (e) => { if (e.target === document.getElementById('schema-modal-overlay')) { document.getElementById('schema-modal-overlay').style.display = 'none'; } }); // Hex-Eingabe → Vorschau aktualisieren document.getElementById('schema-hex-input').addEventListener('input', (e) => { const val = e.target.value.trim(); if (/^#[0-9a-fA-F]{6}$/.test(val)) { aktuelleHex = val; document.getElementById('schema-hex-preview').style.background = val; } }); // Datei-Upload document.getElementById('schema-file-trigger').addEventListener('click', () => { document.getElementById('schema-file-input').click(); }); document.getElementById('schema-file-input').addEventListener('change', (e) => { if (e.target.files[0]) loadImageOnCanvas(e.target.files[0]); }); // Drag & Drop auf Modal-Dropzone const dropzone = document.getElementById('schema-dropzone'); dropzone.addEventListener('dragover', (e) => { e.preventDefault(); dropzone.style.borderColor = '#222'; }); dropzone.addEventListener('dragleave', () => { dropzone.style.borderColor = '#ccc'; }); dropzone.addEventListener('drop', (e) => { e.preventDefault(); dropzone.style.borderColor = '#ccc'; const file = e.dataTransfer.files[0]; if (file && file.type.startsWith('image/')) loadImageOnCanvas(file); }); // Farbe hinzufügen document.getElementById('schema-farbe-hinzufuegen-btn').addEventListener('click', () => { if (!/^#[0-9a-fA-F]{6}$/.test(aktuelleHex)) { document.getElementById('schema-hex-input').style.borderColor = '#e55'; document.getElementById('schema-hex-input').focus(); return; } document.getElementById('schema-hex-input').style.borderColor = ''; const hsl = hexToHsl(aktuelleHex); if (!hsl) return; farben.push(hsl); renderFarbenPreview(); document.getElementById('schema-abschliessen-btn').disabled = false; // Eingabe zurücksetzen aktuelleHex = ''; document.getElementById('schema-hex-input').value = ''; document.getElementById('schema-hex-preview').style.background = '#eee'; document.getElementById('schema-canvas').style.display = 'none'; document.getElementById('schema-file-input').value = ''; if (farben.length >= MAX_FARBEN) { // Alle 4 Farben gesammelt — Eingabe ausblenden document.getElementById('schema-farbe-eingabe').style.display = 'none'; } else { updateFarbeLabel(); document.getElementById('schema-hex-input').focus(); } }); // Abschließen document.getElementById('schema-abschliessen-btn').addEventListener('click', () => { const name = document.getElementById('schema-name-input').value.trim(); if (!name) { document.getElementById('schema-name-input').style.borderColor = '#e55'; document.getElementById('schema-name-input').focus(); return; } if (farben.length === 0) return; onSave(name, farben, vorschaubild); document.getElementById('schema-modal-overlay').style.display = 'none'; }); // Vorschaubild hochladen document.getElementById('schema-bild-trigger').addEventListener('click', () => { document.getElementById('schema-bild-input').click(); }); document.getElementById('schema-bild-input').addEventListener('change', async (e) => { const file = e.target.files[0]; if (!file) return; vorschaubild = await compressToThumbnail(file); const preview = document.getElementById('schema-bild-preview'); preview.style.backgroundImage = 'url(' + vorschaubild + ')'; preview.classList.add('hat-bild'); document.getElementById('schema-bild-entfernen-btn').style.display = 'inline-block'; }); document.getElementById('schema-bild-entfernen-btn').addEventListener('click', () => { vorschaubild = null; const preview = document.getElementById('schema-bild-preview'); preview.style.backgroundImage = ''; preview.classList.remove('hat-bild'); document.getElementById('schema-bild-input').value = ''; document.getElementById('schema-bild-entfernen-btn').style.display = 'none'; }); }