Files
Pigmento/index.html
Ferdinand 446870a94c fix: Logo-Farbe via CSS-Override statt animationData-Reload
lottie cached Daten intern - Mutation+Reload funktioniert nicht.
Neuer Ansatz: gelbe fill-Elemente einmalig mit Klasse markieren,
CSS fill-Property (schlägt SVG-Attribute per Spec) per style-Element
aktualisieren. Kein Reload, kein Flicker.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 17:29:52 +02:00

242 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pigmento</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="lottie-bg"></div>
<header>
<div style="display:flex;align-items:center;gap:0.6rem;margin-bottom:1.25rem">
<div id="lottie-logo" style="width:80px;height:80px;flex-shrink:0"></div>
<h1 style="margin-bottom:0">Pigmento</h1>
</div>
<nav id="main-nav">
<button id="menu-toggle" aria-label="Navigation öffnen">
<span></span><span></span><span></span>
</button>
<span id="menu-active-label">Picker</span>
<div id="menu-dropdown">
<button class="tab-btn active" data-tab="picker">Picker</button>
<button class="tab-btn" data-tab="eingabe">Eingabe</button>
<button class="tab-btn" data-tab="harmonien">Harmonien</button>
<button class="tab-btn" data-tab="sammlung">Sammlung</button>
</div>
</nav>
</header>
<main>
<section id="tab-picker" class="tab-content active">
<h2>Welche Farbe ist das? Bild hochladen und draufklicken.</h2>
<div id="picker-dropzone">
<p>Bild hierher ziehen, einfügen (Strg+V) oder</p>
<button class="action-btn" id="picker-file-trigger">Datei wählen</button>
<input type="file" id="picker-file-input" accept="image/*" style="display:none">
</div>
<canvas id="picker-canvas" style="display:none;max-width:100%;cursor:crosshair;border-radius:8px;border:1px solid #ddd"></canvas>
<div id="picker-result" style="display:none;margin-top:1rem">
<div id="picker-preview" class="color-preview"></div>
<div class="color-codes">
<div class="color-code-group">
<label for="picker-hex">Hex <span class="harmony-info"><span class="harmony-info-icon"></span><span class="harmony-tooltip">Hexadezimale Farbnotation. Rot, Grün und Blau je als zweistellige Hex-Zahl (00FF). Beispiel: #FF5733</span></span></label>
<input id="picker-hex" type="text" readonly>
</div>
<div class="color-code-group">
<label for="picker-rgb">RGB <span class="harmony-info"><span class="harmony-info-icon"></span><span class="harmony-tooltip">Rot, Grün, Blau je 0 bis 255. Additive Mischung wie bei Bildschirmen. Beispiel: 255, 87, 51</span></span></label>
<input id="picker-rgb" type="text" readonly>
</div>
<div class="color-code-group">
<label for="picker-hsl">HSL <span class="harmony-info"><span class="harmony-info-icon"></span><span class="harmony-tooltip">Farbton (Hue, 0360°), Sättigung (0100%) und Helligkeit (Lightness, 0100%). Intuitiver als RGB für Farbkorrekturen.</span></span></label>
<input id="picker-hsl" type="text" readonly>
</div>
</div>
<div class="btn-row">
<button class="action-btn" id="picker-fav-btn">Zu Favoriten</button>
<button class="action-btn" id="picker-schema-btn">Zu Schema hinzufügen</button>
</div>
</div>
</section>
<section id="tab-eingabe" class="tab-content">
<h2>Farbcode eingeben und alle Formate auf einmal sehen.</h2>
<div id="eingabe-preview" class="color-preview" style="background:#3a8fc1"></div>
<div class="color-codes">
<div class="color-code-group">
<label for="eingabe-hex">Hex <span class="harmony-info"><span class="harmony-info-icon"></span><span class="harmony-tooltip">Hexadezimale Farbnotation. Rot, Grün und Blau je als zweistellige Hex-Zahl (00FF). Beispiel: #FF5733</span></span></label>
<input id="eingabe-hex" type="text" value="#3a8fc1" maxlength="7">
</div>
<div class="color-code-group">
<label for="eingabe-rgb">RGB <span class="harmony-info"><span class="harmony-info-icon"></span><span class="harmony-tooltip">Rot, Grün, Blau je 0 bis 255. Additive Mischung wie bei Bildschirmen. Beispiel: 255, 87, 51</span></span></label>
<input id="eingabe-rgb" type="text" value="58, 143, 193">
</div>
<div class="color-code-group">
<label for="eingabe-hsl">HSL <span class="harmony-info"><span class="harmony-info-icon"></span><span class="harmony-tooltip">Farbton (Hue, 0360°), Sättigung (0100%) und Helligkeit (Lightness, 0100%). Intuitiver als RGB für Farbkorrekturen.</span></span></label>
<input id="eingabe-hsl" type="text" value="204, 54%, 49%">
</div>
</div>
<div class="btn-row">
<button class="action-btn" id="eingabe-fav-btn">Zu Favoriten</button>
<button class="action-btn" id="eingabe-schema-btn">Zu Schema hinzufügen</button>
</div>
</section>
<section id="tab-harmonien" class="tab-content">
<h2>Welche Farben passen dazu? Harmonien auf einen Blick.</h2>
<p class="subtitle">Ausgangsfarbe: <span id="harmonien-base-hex">#3a8fc1</span></p>
<div id="harmonien-base-preview" class="color-preview" style="height:50px"></div>
<div id="harmonien-grid" style="display:flex;flex-direction:column;gap:1.5rem;margin-top:1rem"></div>
</section>
<section id="tab-sammlung" class="tab-content">
<h2>Deine gespeicherten Farben, Verläufe und Schemata.</h2>
<div class="btn-row" style="margin-bottom:1.5rem">
<button class="action-btn" id="sammlung-export-btn">Exportieren</button>
<button class="action-btn" id="sammlung-import-btn">Importieren</button>
</div>
<h3>Favoriten</h3>
<div id="sammlung-favoriten" style="display:flex;flex-wrap:wrap;gap:0.5rem;margin-bottom:1.5rem"></div>
<h3>Verlauf (letzte 20)</h3>
<div id="sammlung-history" style="display:flex;flex-wrap:wrap;gap:0.5rem;margin-bottom:1.5rem"></div>
<h3>Farbschemata</h3>
<button class="action-btn" id="schema-erstellen-btn" style="margin-bottom:1rem">+ Schema erstellen</button>
<div id="sammlung-schemata"></div>
</section>
</main>
<!-- Schema-Modal -->
<div id="schema-modal-overlay" class="modal-overlay" style="display:none">
<div class="modal">
<h2 id="schema-modal-title" style="margin-bottom:1rem">Neues Farbschema</h2>
<div class="modal-field">
<label for="schema-name-input">Name</label>
<input id="schema-name-input" type="text" placeholder="z.B. Website Relaunch">
</div>
<div class="modal-field">
<label>Vorschaubild <span style="color:#aaa;font-size:0.7rem;text-transform:none">(optional)</span></label>
<div id="schema-bild-bereich" style="display:flex;align-items:center;gap:0.75rem">
<div id="schema-bild-preview" class="schema-bild-preview"></div>
<div>
<button class="action-btn" id="schema-bild-trigger" type="button">Bild hochladen</button>
<input type="file" id="schema-bild-input" accept="image/*" style="display:none">
<button class="action-btn" id="schema-bild-entfernen-btn" type="button" style="display:none;margin-left:0.4rem;font-size:0.75rem">Entfernen</button>
</div>
</div>
</div>
<div id="schema-farben-preview" class="schema-farben-preview"></div>
<!-- Farbvorschlag aus Bild -->
<div id="schema-vorschlag" style="display:none;margin-bottom:1rem">
<p class="subtitle" style="margin-bottom:0.5rem">Erkannte Farben aus dem Vorschaubild:</p>
<div id="schema-vorschlag-farben" style="display:flex;gap:0.5rem;flex-wrap:wrap;margin-bottom:0.75rem"></div>
<div class="btn-row">
<button class="action-btn" id="schema-vorschlag-annehmen-btn" type="button" style="background:#222;color:#fff;border-color:#222">Vorschlag übernehmen</button>
<button class="action-btn" id="schema-vorschlag-ablehnen-btn" type="button">Manuell eingeben</button>
</div>
</div>
<div id="schema-farbe-eingabe" style="display:none">
<p id="schema-farbe-label" class="subtitle" style="margin-bottom:0.5rem">Farbe 1</p>
<div class="modal-field">
<label for="schema-hex-input">Hex-Code</label>
<div style="display:flex;gap:0.5rem;align-items:center">
<input id="schema-hex-input" type="text" placeholder="#3a8fc1" maxlength="7" style="width:120px">
<div id="schema-hex-preview" style="width:36px;height:36px;border-radius:6px;border:1px solid #ddd;background:#eee;flex-shrink:0"></div>
</div>
</div>
<p class="subtitle" style="margin:0.75rem 0 0.5rem">oder Bild hochladen</p>
<div id="schema-dropzone" class="schema-dropzone">
<p>Bild hier ablegen oder</p>
<button class="action-btn" id="schema-file-trigger" type="button">Datei wählen</button>
<input type="file" id="schema-file-input" accept="image/*" style="display:none">
</div>
<canvas id="schema-canvas" style="display:none;max-width:100%;cursor:crosshair;border-radius:6px;border:1px solid #ddd;margin-top:0.5rem"></canvas>
<div class="btn-row" style="margin-top:1rem">
<button class="action-btn" id="schema-farbe-hinzufuegen-btn" type="button">Farbe hinzufügen</button>
</div>
</div>
<div class="btn-row" style="margin-top:1.5rem;justify-content:space-between">
<button class="action-btn" id="schema-abbrechen-btn" type="button">Abbrechen</button>
<button class="action-btn" id="schema-abschliessen-btn" type="button" style="background:#222;color:#fff;border-color:#222" disabled>Abschließen</button>
</div>
</div>
</div>
<script>
const _bg = ['#F5DFE3','#F5E6DF','#F5F2DF','#E3F5DF','#DFF5F0','#E9DFF5','#F5DFF0','#DFE9F5'];
document.body.style.background = _bg[Math.floor(Math.random() * _bg.length)];
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js"></script>
<script type="module" src="js/app.js"></script>
<script>
// Hintergrund-Animation
lottie.loadAnimation({
container: document.getElementById('lottie-bg'),
renderer: 'svg',
loop: true,
autoplay: true,
path: 'Background Grey Wave.json'
});
// Logo-Animation mit dynamischer Farbsteuerung via CSS-Override
// (CSS fill-Property schlägt SVG fill-Attribute per Spec)
let _logoAnim = lottie.loadAnimation({
container: document.getElementById('lottie-logo'),
renderer: 'svg',
loop: true,
autoplay: true,
path: 'Fluid Loading Animation.json'
});
let _logoStyleEl = null;
let _yellowMarked = false;
function _hslToHex(h, s, l) {
s /= 100; l /= 100;
const a = s * Math.min(l, 1 - l);
const f = n => {
const k = (n + h / 30) % 12;
return Math.round(255 * (l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)))
.toString(16).padStart(2, '0');
};
return '#' + f(0) + f(8) + f(4);
}
function _markYellowElements() {
const svg = document.querySelector('#lottie-logo svg');
if (!svg) return false;
svg.querySelectorAll('[fill="rgb(255,223,0)"]').forEach(el => {
el.classList.add('logo-primary-fill');
});
return svg.querySelector('.logo-primary-fill') !== null;
}
function setLogoColor(hex) {
if (!_yellowMarked) {
_yellowMarked = _markYellowElements();
if (!_yellowMarked) return;
}
if (!_logoStyleEl) {
_logoStyleEl = document.createElement('style');
document.head.appendChild(_logoStyleEl);
}
_logoStyleEl.textContent = '#lottie-logo .logo-primary-fill { fill: ' + hex + '; }';
}
document.addEventListener('colorChanged', (e) => {
const hex = _hslToHex(e.detail.h, e.detail.s, e.detail.l);
setLogoColor(hex);
});
</script>
</body>
</html>