diff --git a/index.html b/index.html index 9cd67a7..38b05b1 100644 --- a/index.html +++ b/index.html @@ -106,6 +106,18 @@ + +
diff --git a/js/collection.js b/js/collection.js index fda00a6..dd7d4c0 100644 --- a/js/collection.js +++ b/js/collection.js @@ -74,13 +74,14 @@ export function addColorToSchema(hsl) { } } -export function saveSchema(name, farben) { +export function saveSchema(name, farben, bild) { const data = load(); const existing = data.schemata.find(s => s.name === name); if (existing) { existing.farben = farben; + if (bild !== undefined) existing.bild = bild || null; } else { - data.schemata.push({ name, farben }); + data.schemata.push({ name, farben, bild: bild || null }); } save(data); renderSammlung(); @@ -227,8 +228,20 @@ export function renderSammlung() { const header = document.createElement('div'); header.style.cssText = 'display:flex;justify-content:space-between;align-items:center;margin-bottom:0.5rem'; + // Thumbnail + Name nebeneinander + const nameRow = document.createElement('div'); + nameRow.style.cssText = 'display:flex;align-items:center;gap:0.6rem'; + + if (schema.bild) { + const thumb = document.createElement('div'); + thumb.className = 'schema-thumb'; + thumb.style.backgroundImage = 'url(' + schema.bild + ')'; + nameRow.appendChild(thumb); + } + const nameEl = document.createElement('strong'); nameEl.textContent = schema.name; + nameRow.appendChild(nameEl); const delBtn = document.createElement('button'); delBtn.className = 'action-btn'; @@ -236,7 +249,7 @@ export function renderSammlung() { delBtn.style.fontSize = '0.75rem'; delBtn.addEventListener('click', () => deleteSchema(schema.name)); - header.appendChild(nameEl); + header.appendChild(nameRow); header.appendChild(delBtn); const swatchesDiv = document.createElement('div'); diff --git a/js/schema-modal.js b/js/schema-modal.js index 767f842..3b438b8 100644 --- a/js/schema-modal.js +++ b/js/schema-modal.js @@ -1,14 +1,38 @@ 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 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'; @@ -17,6 +41,12 @@ function resetModal() { 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(); } @@ -186,7 +216,31 @@ export function initSchemaModal(onSave) { } if (farben.length === 0) return; - onSave(name, farben); + 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'; + }); } diff --git a/style.css b/style.css index 01acb01..f15f614 100644 --- a/style.css +++ b/style.css @@ -225,6 +225,30 @@ button.action-btn:hover { background: #f0f0f0; } .schema-dropzone p { margin-bottom: 0.5rem; } +/* Vorschaubild im Modal */ +.schema-bild-preview { + width: 56px; + height: 56px; + border-radius: 8px; + border: 2px dashed #ddd; + background: #f5f5f5; + background-size: cover; + background-position: center; + flex-shrink: 0; +} +.schema-bild-preview.hat-bild { border-style: solid; border-color: #ccc; } + +/* Thumbnail in der Sammlung */ +.schema-thumb { + width: 40px; + height: 40px; + border-radius: 6px; + border: 1px solid #ddd; + background-size: cover; + background-position: center; + flex-shrink: 0; +} + /* --- Finale Styles --- */ h2 { font-size: 1.1rem; margin-bottom: 1rem; } h3 { font-size: 0.95rem; margin-bottom: 0.5rem; }