feat: Harmonien-Tab mit Komplementar, Analog, Triade, Split-Komplementar
This commit is contained in:
@@ -71,8 +71,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section id="tab-harmonien" class="tab-content">
|
<section id="tab-harmonien" class="tab-content">
|
||||||
<p>Harmonien kommen hier</p>
|
<h2>Farbharmonien</h2>
|
||||||
</section>
|
<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">
|
<section id="tab-sammlung" class="tab-content">
|
||||||
<p>Sammlung kommt hier</p>
|
<p>Sammlung kommt hier</p>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { initEingabe } from './eingabe.js';
|
import { initEingabe } from './eingabe.js';
|
||||||
import { initPicker } from './picker.js';
|
import { initPicker } from './picker.js';
|
||||||
|
import { initHarmonien } from './harmonien.js';
|
||||||
|
|
||||||
// Globaler State — aktive Farbe als { h, s, l } (HSL, 0-360, 0-100, 0-100)
|
// 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,
|
// state.color is read-only from outside — always use setColor() to update,
|
||||||
@@ -30,3 +31,4 @@ function addColorToSchema(hsl) { console.log('addColorToSchema', hsl); }
|
|||||||
|
|
||||||
initEingabe(addFavorit, addColorToSchema);
|
initEingabe(addFavorit, addColorToSchema);
|
||||||
initPicker(addFavorit, addColorToSchema);
|
initPicker(addFavorit, addColorToSchema);
|
||||||
|
initHarmonien(addFavorit, addColorToSchema);
|
||||||
|
|||||||
77
js/harmonien.js
Normal file
77
js/harmonien.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import { getHarmonies, hslToHex } from './converter.js';
|
||||||
|
import { state } from './app.js';
|
||||||
|
|
||||||
|
function renderHarmony(label, colors, onSaveFavorit, onSaveSchema) {
|
||||||
|
const row = document.createElement('div');
|
||||||
|
row.className = 'harmony-row';
|
||||||
|
|
||||||
|
const heading = document.createElement('h3');
|
||||||
|
heading.textContent = label;
|
||||||
|
row.appendChild(heading);
|
||||||
|
|
||||||
|
const swatchesDiv = document.createElement('div');
|
||||||
|
swatchesDiv.className = 'harmony-swatches';
|
||||||
|
|
||||||
|
colors.forEach(hsl => {
|
||||||
|
const hex = hslToHex(hsl);
|
||||||
|
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.className = 'harmony-swatch';
|
||||||
|
|
||||||
|
const swatch = document.createElement('div');
|
||||||
|
swatch.className = 'swatch';
|
||||||
|
swatch.style.background = hex;
|
||||||
|
swatch.title = hex;
|
||||||
|
|
||||||
|
const hexLabel = document.createElement('span');
|
||||||
|
hexLabel.textContent = hex;
|
||||||
|
|
||||||
|
const btnRow = document.createElement('div');
|
||||||
|
btnRow.style.cssText = 'display:flex;gap:0.25rem';
|
||||||
|
|
||||||
|
const favBtn = document.createElement('button');
|
||||||
|
favBtn.className = 'action-btn';
|
||||||
|
favBtn.textContent = 'Fav';
|
||||||
|
favBtn.style.fontSize = '0.7rem';
|
||||||
|
favBtn.addEventListener('click', () => onSaveFavorit(hsl));
|
||||||
|
|
||||||
|
const schemaBtn = document.createElement('button');
|
||||||
|
schemaBtn.className = 'action-btn';
|
||||||
|
schemaBtn.textContent = '+Schema';
|
||||||
|
schemaBtn.style.fontSize = '0.7rem';
|
||||||
|
schemaBtn.addEventListener('click', () => onSaveSchema(hsl));
|
||||||
|
|
||||||
|
btnRow.appendChild(favBtn);
|
||||||
|
btnRow.appendChild(schemaBtn);
|
||||||
|
|
||||||
|
div.appendChild(swatch);
|
||||||
|
div.appendChild(hexLabel);
|
||||||
|
div.appendChild(btnRow);
|
||||||
|
swatchesDiv.appendChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
row.appendChild(swatchesDiv);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
function render(onSaveFavorit, onSaveSchema) {
|
||||||
|
const hsl = state.color;
|
||||||
|
const hex = hslToHex(hsl);
|
||||||
|
|
||||||
|
document.getElementById('harmonien-base-hex').textContent = hex;
|
||||||
|
document.getElementById('harmonien-base-preview').style.background = hex;
|
||||||
|
|
||||||
|
const grid = document.getElementById('harmonien-grid');
|
||||||
|
grid.textContent = '';
|
||||||
|
|
||||||
|
const h = getHarmonies(hsl);
|
||||||
|
grid.appendChild(renderHarmony('Komplementar', h.komplementaer, onSaveFavorit, onSaveSchema));
|
||||||
|
grid.appendChild(renderHarmony('Analog', h.analog, onSaveFavorit, onSaveSchema));
|
||||||
|
grid.appendChild(renderHarmony('Triade', h.triade, onSaveFavorit, onSaveSchema));
|
||||||
|
grid.appendChild(renderHarmony('Split-Komplementar', h.splitKomplementaer, onSaveFavorit, onSaveSchema));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initHarmonien(onSaveFavorit, onSaveSchema) {
|
||||||
|
document.addEventListener('colorChanged', () => render(onSaveFavorit, onSaveSchema));
|
||||||
|
render(onSaveFavorit, onSaveSchema);
|
||||||
|
}
|
||||||
14
style.css
14
style.css
@@ -103,3 +103,17 @@ button.action-btn:hover { background: #f0f0f0; }
|
|||||||
}
|
}
|
||||||
|
|
||||||
#picker-dropzone p { margin-bottom: 0.75rem; color: #666; font-size: 0.9rem; }
|
#picker-dropzone p { margin-bottom: 0.75rem; color: #666; font-size: 0.9rem; }
|
||||||
|
|
||||||
|
/* --- Harmonien-Tab --- */
|
||||||
|
.subtitle { font-size: 0.85rem; color: #666; margin-bottom: 0.5rem; }
|
||||||
|
|
||||||
|
.harmony-row h3 { font-size: 0.9rem; margin-bottom: 0.5rem; }
|
||||||
|
.harmony-swatches { display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: flex-start; }
|
||||||
|
.harmony-swatch {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
.harmony-swatch .swatch { width: 56px; height: 56px; }
|
||||||
|
.harmony-swatch span { font-size: 0.75rem; font-family: monospace; }
|
||||||
|
|||||||
Reference in New Issue
Block a user