feat(ui): compact Color Wheels & Match panel with MiniSlider rulers and 4-column color bands
This commit is contained in:
+112
-77
@@ -4028,7 +4028,7 @@ export function Workspace() {
|
||||
<div>
|
||||
<span className="dev-box-title" style={{ marginBottom: '6px', display: 'block' }}>COLOR BANDS</span>
|
||||
<ChipRow
|
||||
grid
|
||||
grid4
|
||||
chips={HSL_BANDS.map((b) => {
|
||||
const band = recipe.adjustments.hslBands?.[b.id];
|
||||
const moved = !!band && (band[0] !== 0 || band[1] !== 0 || band[2] !== 0);
|
||||
@@ -4050,7 +4050,7 @@ export function Workspace() {
|
||||
|
||||
{hslBand && (
|
||||
<div className="dev-subgroup" style={{ marginTop: '4px' }}>
|
||||
<div className="dev-subgroup-title" style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div className="dev-subgroup-title" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<span>BAND: {HSL_BANDS.find((b) => b.id === hslBand)?.label}</span>
|
||||
{(recipe.adjustments.hslBands?.[hslBand]?.[0] || recipe.adjustments.hslBands?.[hslBand]?.[1] || recipe.adjustments.hslBands?.[hslBand]?.[2]) ? (
|
||||
<button
|
||||
@@ -4082,39 +4082,45 @@ export function Workspace() {
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div className="dev-row">
|
||||
<span className="dev-row-label">Hue</span>
|
||||
<input
|
||||
type="range"
|
||||
min={-30}
|
||||
max={30}
|
||||
value={bandVals[0]}
|
||||
onChange={(e) => updateBand(0, Number(e.target.value))}
|
||||
/>
|
||||
<span className="dev-row-value">{bandVals[0] > 0 ? `+${bandVals[0]}` : bandVals[0]}</span>
|
||||
</div>
|
||||
<div className="dev-row">
|
||||
<span className="dev-row-label">Saturation</span>
|
||||
<input
|
||||
type="range"
|
||||
min={-100}
|
||||
max={100}
|
||||
value={bandVals[1]}
|
||||
onChange={(e) => updateBand(1, Number(e.target.value))}
|
||||
/>
|
||||
<span className="dev-row-value">{bandVals[1] > 0 ? `+${bandVals[1]}` : bandVals[1]}</span>
|
||||
</div>
|
||||
<div className="dev-row">
|
||||
<span className="dev-row-label">Luminance</span>
|
||||
<input
|
||||
type="range"
|
||||
min={-100}
|
||||
max={100}
|
||||
value={bandVals[2]}
|
||||
onChange={(e) => updateBand(2, Number(e.target.value))}
|
||||
/>
|
||||
<span className="dev-row-value">{bandVals[2] > 0 ? `+${bandVals[2]}` : bandVals[2]}</span>
|
||||
</div>
|
||||
<MiniSlider
|
||||
label="Hue"
|
||||
value={bandVals[0]}
|
||||
min={-10}
|
||||
max={10}
|
||||
step={1}
|
||||
defaultValue={0}
|
||||
format={(v) => v.toFixed(1)}
|
||||
prefix={`dev-hsl-${hslBand}`}
|
||||
dataKey={`dev-hsl-${hslBand}-hue`}
|
||||
onChange={(v) => updateBand(0, v)}
|
||||
onReset={() => updateBand(0, 0)}
|
||||
/>
|
||||
<MiniSlider
|
||||
label="Saturation"
|
||||
value={bandVals[1]}
|
||||
min={-10}
|
||||
max={10}
|
||||
step={1}
|
||||
defaultValue={0}
|
||||
format={(v) => v.toFixed(1)}
|
||||
prefix={`dev-hsl-${hslBand}`}
|
||||
dataKey={`dev-hsl-${hslBand}-sat`}
|
||||
onChange={(v) => updateBand(1, v)}
|
||||
onReset={() => updateBand(1, 0)}
|
||||
/>
|
||||
<MiniSlider
|
||||
label="Luminance"
|
||||
value={bandVals[2]}
|
||||
min={-10}
|
||||
max={10}
|
||||
step={1}
|
||||
defaultValue={0}
|
||||
format={(v) => v.toFixed(1)}
|
||||
prefix={`dev-hsl-${hslBand}`}
|
||||
dataKey={`dev-hsl-${hslBand}-lum`}
|
||||
onChange={(v) => updateBand(2, v)}
|
||||
onReset={() => updateBand(2, 0)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
})()}
|
||||
@@ -4122,49 +4128,78 @@ export function Workspace() {
|
||||
)}
|
||||
|
||||
<div className="dev-subgroup" style={{ marginTop: '4px' }}>
|
||||
<div className="dev-subgroup-title">IMAGE MASTER</div>
|
||||
<div className="dev-row">
|
||||
<span className="dev-row-label">Hue</span>
|
||||
<input
|
||||
type="range"
|
||||
min={-180}
|
||||
max={180}
|
||||
value={recipe.adjustments.hslHue ?? 0}
|
||||
onChange={(e) => {
|
||||
remember();
|
||||
setAdjustment({ hslHue: Number(e.target.value) });
|
||||
}}
|
||||
/>
|
||||
<span className="dev-row-value">{(recipe.adjustments.hslHue ?? 0) > 0 ? `+${recipe.adjustments.hslHue}` : recipe.adjustments.hslHue ?? 0}</span>
|
||||
</div>
|
||||
<div className="dev-row">
|
||||
<span className="dev-row-label">Saturation</span>
|
||||
<input
|
||||
type="range"
|
||||
min={-100}
|
||||
max={100}
|
||||
value={recipe.adjustments.hslSat ?? 0}
|
||||
onChange={(e) => {
|
||||
remember();
|
||||
setAdjustment({ hslSat: Number(e.target.value) });
|
||||
}}
|
||||
/>
|
||||
<span className="dev-row-value">{(recipe.adjustments.hslSat ?? 0) > 0 ? `+${recipe.adjustments.hslSat}` : recipe.adjustments.hslSat ?? 0}</span>
|
||||
</div>
|
||||
<div className="dev-row">
|
||||
<span className="dev-row-label">Luminance</span>
|
||||
<input
|
||||
type="range"
|
||||
min={-100}
|
||||
max={100}
|
||||
value={recipe.adjustments.hslLum ?? 0}
|
||||
onChange={(e) => {
|
||||
remember();
|
||||
setAdjustment({ hslLum: Number(e.target.value) });
|
||||
}}
|
||||
/>
|
||||
<span className="dev-row-value">{(recipe.adjustments.hslLum ?? 0) > 0 ? `+${recipe.adjustments.hslLum}` : recipe.adjustments.hslLum ?? 0}</span>
|
||||
<div className="dev-subgroup-title" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<span>IMAGE MASTER</span>
|
||||
{((recipe.adjustments.hslHue ?? 0) !== 0 || (recipe.adjustments.hslSat ?? 0) !== 0 || (recipe.adjustments.hslLum ?? 0) !== 0) ? (
|
||||
<button
|
||||
type="button"
|
||||
style={{ background: 'none', border: 'none', color: 'var(--accent)', cursor: 'pointer', fontSize: '10px' }}
|
||||
onClick={() => {
|
||||
remember();
|
||||
setAdjustment({ hslHue: 0, hslSat: 0, hslLum: 0 });
|
||||
}}
|
||||
>
|
||||
RESET
|
||||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
<MiniSlider
|
||||
label="Hue"
|
||||
value={recipe.adjustments.hslHue ?? 0}
|
||||
min={-10}
|
||||
max={10}
|
||||
step={1}
|
||||
defaultValue={0}
|
||||
format={(v) => v.toFixed(1)}
|
||||
prefix="dev-hsl-master"
|
||||
dataKey="dev-hsl-master-hue"
|
||||
onChange={(v) => {
|
||||
remember();
|
||||
setAdjustment({ hslHue: v });
|
||||
}}
|
||||
onReset={() => {
|
||||
remember();
|
||||
setAdjustment({ hslHue: 0 });
|
||||
}}
|
||||
/>
|
||||
<MiniSlider
|
||||
label="Saturation"
|
||||
value={recipe.adjustments.hslSat ?? 0}
|
||||
min={-10}
|
||||
max={10}
|
||||
step={1}
|
||||
defaultValue={0}
|
||||
format={(v) => v.toFixed(1)}
|
||||
prefix="dev-hsl-master"
|
||||
dataKey="dev-hsl-master-sat"
|
||||
onChange={(v) => {
|
||||
remember();
|
||||
setAdjustment({ hslSat: v });
|
||||
}}
|
||||
onReset={() => {
|
||||
remember();
|
||||
setAdjustment({ hslSat: 0 });
|
||||
}}
|
||||
/>
|
||||
<MiniSlider
|
||||
label="Luminance"
|
||||
value={recipe.adjustments.hslLum ?? 0}
|
||||
min={-10}
|
||||
max={10}
|
||||
step={1}
|
||||
defaultValue={0}
|
||||
format={(v) => v.toFixed(1)}
|
||||
prefix="dev-hsl-master"
|
||||
dataKey="dev-hsl-master-lum"
|
||||
onChange={(v) => {
|
||||
remember();
|
||||
setAdjustment({ hslLum: v });
|
||||
}}
|
||||
onReset={() => {
|
||||
remember();
|
||||
setAdjustment({ hslLum: 0 });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user