diff --git a/index.html b/index.html index 9dfc77c..9e0fcc6 100644 --- a/index.html +++ b/index.html @@ -19,8 +19,35 @@
-

Picker kommt hier

-
+

Farbe aus Bild

+
+

Bild hierher ziehen, einfügen (Strg+V) oder

+ + +
+ + +

Farbe eingeben

diff --git a/js/app.js b/js/app.js index bda9a6c..b3c40ed 100644 --- a/js/app.js +++ b/js/app.js @@ -1,4 +1,5 @@ import { initEingabe } from './eingabe.js'; +import { initPicker } from './picker.js'; // Globaler State — aktive Farbe als { h, s, l } (HSL, 0-360, 0-100, 0-100) // state.color is read-only from outside — always use setColor() to update, @@ -28,3 +29,4 @@ function addFavorit(hsl) { console.log('addFavorit', hsl); } function addColorToSchema(hsl) { console.log('addColorToSchema', hsl); } initEingabe(addFavorit, addColorToSchema); +initPicker(addFavorit, addColorToSchema); diff --git a/js/picker.js b/js/picker.js new file mode 100644 index 0000000..14429a3 --- /dev/null +++ b/js/picker.js @@ -0,0 +1,83 @@ +import { rgbToHex, rgbToHsl } from './converter.js'; +import { state } from './app.js'; + +function rgbToDisplay({ r, g, b }) { return r + ', ' + g + ', ' + b; } +function hslToDisplay({ h, s, l }) { return h + ', ' + s + '%, ' + l + '%'; } + +function showColor(r, g, b) { + const hex = rgbToHex({ r, g, b }); + const hsl = rgbToHsl({ r, g, b }); + state.setColor(hsl); + document.getElementById('picker-preview').style.background = hex; + document.getElementById('picker-hex').value = hex; + document.getElementById('picker-rgb').value = rgbToDisplay({ r, g, b }); + document.getElementById('picker-hsl').value = hslToDisplay(hsl); + document.getElementById('picker-result').style.display = 'block'; +} + +function loadImage(file) { + const reader = new FileReader(); + reader.onload = (e) => { + const img = new Image(); + img.onload = () => { + const canvas = document.getElementById('picker-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 mx = Math.floor(img.width / 2); + const my = Math.floor(img.height / 2); + const px = ctx.getImageData(mx, my, 1, 1).data; + showColor(px[0], px[1], px[2]); + + // Eyedropper: Klick wählt Pixel frei + canvas.onclick = (ev) => { + const rect = canvas.getBoundingClientRect(); + const scaleX = canvas.width / rect.width; + const scaleY = canvas.height / rect.height; + const x = Math.floor((ev.clientX - rect.left) * scaleX); + const y = Math.floor((ev.clientY - rect.top) * scaleY); + const d = ctx.getImageData(x, y, 1, 1).data; + showColor(d[0], d[1], d[2]); + }; + }; + img.src = e.target.result; + }; + reader.readAsDataURL(file); +} + +export function initPicker(onSaveFavorit, onSaveSchema) { + const dropzone = document.getElementById('picker-dropzone'); + + document.getElementById('picker-file-trigger').addEventListener('click', () => { + document.getElementById('picker-file-input').click(); + }); + + document.getElementById('picker-file-input').addEventListener('change', (e) => { + if (e.target.files[0]) loadImage(e.target.files[0]); + }); + + dropzone.addEventListener('dragover', (e) => { + e.preventDefault(); + dropzone.classList.add('drag-over'); + }); + dropzone.addEventListener('dragleave', () => dropzone.classList.remove('drag-over')); + dropzone.addEventListener('drop', (e) => { + e.preventDefault(); + dropzone.classList.remove('drag-over'); + const file = e.dataTransfer.files[0]; + if (file && file.type.startsWith('image/')) loadImage(file); + }); + + // Paste (Strg+V / Cmd+V) + document.addEventListener('paste', (e) => { + const item = Array.from(e.clipboardData.items).find(i => i.type.startsWith('image/')); + if (item) loadImage(item.getAsFile()); + }); + + document.getElementById('picker-fav-btn').addEventListener('click', () => onSaveFavorit(state.color)); + document.getElementById('picker-schema-btn').addEventListener('click', () => onSaveSchema(state.color)); +} diff --git a/style.css b/style.css index 8af2658..7e8a4d6 100644 --- a/style.css +++ b/style.css @@ -87,3 +87,19 @@ button.action-btn:hover { background: #f0f0f0; } cursor: pointer; vertical-align: middle; } + +#picker-dropzone { + border: 2px dashed #ccc; + border-radius: 8px; + padding: 2rem; + text-align: center; + margin-bottom: 1rem; + background: #fafafa; +} + +#picker-dropzone.drag-over { + border-color: #222; + background: #f0f0f0; +} + +#picker-dropzone p { margin-bottom: 0.75rem; color: #666; font-size: 0.9rem; }