Additional shaders
Some checks failed
CI / Native Windows Build And Tests (push) Has been cancelled
CI / React UI Build (push) Has been cancelled
CI / Windows Release Package (push) Has been cancelled

This commit is contained in:
2026-05-06 00:23:20 +10:00
parent cf31c91831
commit 437199f3f0
9 changed files with 349 additions and 39 deletions

View File

@@ -190,43 +190,70 @@ export function ParameterField({ layer, parameter, onParameterChange }) {
while (values.length < 4) {
values.push(values.length === 3 ? 1 : 0);
}
const hsva = colorValueToHsva(values);
const wheelHsva = { ...hsva, v: 100 };
const sendHsva = (nextHsva) => scheduleSendValue(hsvaToColorValue(nextHsva, values[3]));
return (
<section className="parameter">
{header}
<div className="parameter__wheel-row">
<div
className="parameter__wheel"
onPointerDown={beginInteraction}
onPointerUp={endInteraction}
onPointerCancel={endInteraction}
onBlur={endInteraction}
>
<Wheel
color={colorValueToHsva(values)}
width={132}
height={132}
onChange={(color) => scheduleSendValue(hsvaToColorValue(color.hsva, values[3]))}
/>
</div>
<label className="parameter__alpha">
<span>Alpha</span>
<input
type="number"
min={parameter.min?.[3] ?? 0}
max={parameter.max?.[3] ?? 1}
step={parameter.step?.[3] ?? 0.01}
value={values[3]}
onFocus={beginInteraction}
onChange={(event) => {
const next = [...values];
next[3] = Number(event.target.value);
sendValue(next);
}}
<div className="parameter__color-stack">
<div
className="parameter__wheel"
onPointerDown={beginInteraction}
onPointerUp={endInteraction}
onPointerCancel={endInteraction}
onBlur={endInteraction}
/>
</label>
<div className="parameter__swatch" style={{ background: colorValueToHex(values) }} aria-hidden="true" />
>
<Wheel
color={wheelHsva}
width={196}
height={196}
onChange={(color) => sendHsva({ ...color.hsva, v: hsva.v })}
/>
</div>
<label className="parameter__value-slider">
<input
type="range"
min={0}
max={100}
step={1}
value={Math.round(hsva.v)}
aria-label={`${parameter.label} value`}
onMouseDown={beginInteraction}
onPointerDown={beginInteraction}
onTouchStart={beginInteraction}
onChange={(event) => sendHsva({ ...hsva, v: Number(event.target.value) })}
onMouseUp={endInteraction}
onTouchEnd={endInteraction}
onPointerUp={endInteraction}
onKeyDown={beginInteraction}
onKeyUp={endInteraction}
onBlur={endInteraction}
/>
</label>
</div>
<div className="parameter__color-bottom">
<label className="parameter__alpha">
<span>Alpha</span>
<input
type="number"
min={parameter.min?.[3] ?? 0}
max={parameter.max?.[3] ?? 1}
step={parameter.step?.[3] ?? 0.01}
value={values[3]}
onFocus={beginInteraction}
onChange={(event) => {
const next = [...values];
next[3] = Number(event.target.value);
sendValue(next);
}}
onBlur={endInteraction}
/>
</label>
<div className="parameter__swatch" style={{ background: colorValueToHex(values) }} aria-hidden="true" />
</div>
</div>
<ParameterValueDisplay parameterType={parameter.type} value={appliedValue} pending={isPending} />
</section>

View File

@@ -858,14 +858,23 @@ pre {
.parameter__wheel-row {
display: grid;
grid-template-columns: auto minmax(5.25rem, 1fr);
gap: 0.5rem;
grid-template-columns: minmax(0, 196px);
gap: 0.625rem;
align-items: start;
justify-content: center;
}
.parameter__color-stack {
display: grid;
gap: 0.625rem;
width: 196px;
}
.parameter__wheel {
width: 132px;
height: 132px;
width: 196px;
height: 196px;
overflow: hidden;
border-radius: 50%;
}
.parameter__wheel [class*="react-colorful"],
@@ -873,14 +882,87 @@ pre {
max-width: 100%;
}
.parameter__wheel svg,
.parameter__wheel canvas {
display: block;
}
.parameter__color-bottom {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(4.5rem, 0.85fr);
gap: 0.625rem;
align-items: end;
width: 196px;
}
.parameter__swatch {
grid-column: 2;
width: 100%;
min-height: 28px;
min-height: 38px;
border: 1px solid var(--app-border);
border-radius: var(--app-radius-sm);
}
.parameter__value-slider {
display: block;
width: 196px;
}
.parameter__value-slider input[type="range"] {
--value-thumb-size: 18px;
display: block;
width: 196px;
height: 22px;
margin: 0;
accent-color: #f2f6fb;
background: linear-gradient(90deg, #000 0%, #fff 100%);
border-radius: 999px;
cursor: pointer;
appearance: none;
-webkit-appearance: none;
}
.parameter__value-slider input[type="range"]::-webkit-slider-runnable-track {
height: 0.75rem;
border: 1px solid rgba(255, 255, 255, 0.28);
border-radius: 999px;
background: linear-gradient(90deg, #000 0%, #fff 100%);
}
.parameter__value-slider input[type="range"]::-webkit-slider-thumb {
width: var(--value-thumb-size);
height: var(--value-thumb-size);
margin-top: calc((0.75rem - var(--value-thumb-size)) / 2);
border: 2px solid #f7fbff;
border-radius: 999px;
background: #f7fbff;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.65), 0 1px 4px rgba(0, 0, 0, 0.45);
-webkit-appearance: none;
}
.parameter__value-slider input[type="range"]::-moz-range-track {
height: 0.75rem;
border: 1px solid rgba(255, 255, 255, 0.28);
border-radius: 999px;
background: linear-gradient(90deg, #000 0%, #fff 100%);
}
.parameter__value-slider input[type="range"]::-moz-range-thumb {
width: var(--value-thumb-size);
height: var(--value-thumb-size);
border: 2px solid #f7fbff;
border-radius: 999px;
background: #f7fbff;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.65), 0 1px 4px rgba(0, 0, 0, 0.45);
}
.parameter__value-slider strong {
text-align: right;
min-height: 1rem;
color: var(--app-text);
font-size: 0.74rem;
line-height: 1;
}
.parameter__alpha {
display: grid;
gap: 0.25rem;
@@ -975,6 +1057,13 @@ pre {
grid-column: auto;
}
.parameter__color-stack,
.parameter__color-bottom,
.parameter__value-slider,
.parameter__value-slider input[type="range"] {
width: 100%;
}
.kv-row {
grid-template-columns: minmax(6.25rem, 0.6fr) minmax(0, 1fr);
}