radio instead of slider for jitter
This commit is contained in:
parent
1aa72d6412
commit
760bb0cdb1
@ -89,6 +89,43 @@
|
|||||||
accent-color: var(--accent);
|
accent-color: var(--accent);
|
||||||
height: 4px;
|
height: 4px;
|
||||||
}
|
}
|
||||||
|
.segmented {
|
||||||
|
grid-column: 2 / -1;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(6, 1fr);
|
||||||
|
border: 1px solid var(--hair);
|
||||||
|
background: var(--panel);
|
||||||
|
}
|
||||||
|
.segmented label {
|
||||||
|
font-family: "JetBrains Mono", "SF Mono", Menlo, Monaco, monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 7px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--muted);
|
||||||
|
border-left: 1px solid var(--hair);
|
||||||
|
transition: background 120ms ease, color 120ms ease;
|
||||||
|
user-select: none;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.segmented label:first-of-type { border-left: none; }
|
||||||
|
.segmented label:hover { color: var(--text); background: rgba(31, 78, 95, 0.06); }
|
||||||
|
.segmented label:has(input:checked) {
|
||||||
|
background: var(--accent);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.segmented label:has(input:focus-visible) {
|
||||||
|
outline: 2px solid var(--accent);
|
||||||
|
outline-offset: -2px;
|
||||||
|
}
|
||||||
|
.segmented input[type="radio"] {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
.lede kbd {
|
.lede kbd {
|
||||||
font-family: "JetBrains Mono", "SF Mono", Menlo, Monaco, monospace;
|
font-family: "JetBrains Mono", "SF Mono", Menlo, Monaco, monospace;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -301,17 +338,15 @@
|
|||||||
<input type="range" id="n-slider" min="100" max="5000" step="100" value="500">
|
<input type="range" id="n-slider" min="100" max="5000" step="100" value="500">
|
||||||
<span class="ctl-value" id="n-value">500</span>
|
<span class="ctl-value" id="n-value">500</span>
|
||||||
|
|
||||||
<label class="ctl-label" for="j-slider">noise σ</label>
|
<span class="ctl-label">noise σ</span>
|
||||||
<input type="range" id="j-slider" min="0" max="5" step="1" value="1" list="j-levels">
|
<div class="segmented" role="radiogroup" aria-label="noise σ">
|
||||||
<datalist id="j-levels">
|
<label><input type="radio" name="j" value="0"><span>0.00</span></label>
|
||||||
<option value="0"></option>
|
<label><input type="radio" name="j" value="0.01" checked><span>0.01</span></label>
|
||||||
<option value="1"></option>
|
<label><input type="radio" name="j" value="0.05"><span>0.05</span></label>
|
||||||
<option value="2"></option>
|
<label><input type="radio" name="j" value="0.1"><span>0.10</span></label>
|
||||||
<option value="3"></option>
|
<label><input type="radio" name="j" value="0.15"><span>0.15</span></label>
|
||||||
<option value="4"></option>
|
<label><input type="radio" name="j" value="0.2"><span>0.20</span></label>
|
||||||
<option value="5"></option>
|
</div>
|
||||||
</datalist>
|
|
||||||
<span class="ctl-value" id="j-value">0.01</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gallery" id="gallery">
|
<div class="gallery" id="gallery">
|
||||||
@ -554,17 +589,18 @@ async function main() {
|
|||||||
slider.addEventListener('input', (e) => applyN(parseInt(e.target.value, 10)));
|
slider.addEventListener('input', (e) => applyN(parseInt(e.target.value, 10)));
|
||||||
applyN(parseInt(slider.value, 10));
|
applyN(parseInt(slider.value, 10));
|
||||||
|
|
||||||
// Noise slider → rewrites positions each frame in the render loop.
|
// Noise is a 6-level radio group; value is the σ directly.
|
||||||
let jitterScale = 0;
|
let jitterScale = 0;
|
||||||
const jSlider = document.getElementById('j-slider');
|
const jInputs = document.querySelectorAll('input[name="j"]');
|
||||||
const jValue = document.getElementById('j-value');
|
|
||||||
function applyJ(v) {
|
function applyJ(v) {
|
||||||
jitterScale = v;
|
jitterScale = v;
|
||||||
jValue.textContent = v.toFixed(2);
|
|
||||||
updateContinue();
|
updateContinue();
|
||||||
}
|
}
|
||||||
jSlider.addEventListener('input', (e) => applyJ(parseFloat(e.target.value)));
|
jInputs.forEach(input => {
|
||||||
applyJ(parseFloat(jSlider.value));
|
input.addEventListener('change', (e) => applyJ(parseFloat(e.target.value)));
|
||||||
|
});
|
||||||
|
const jChecked = document.querySelector('input[name="j"]:checked');
|
||||||
|
applyJ(parseFloat(jChecked.value));
|
||||||
|
|
||||||
// Keyboard: digits jump directly, arrows step.
|
// Keyboard: digits jump directly, arrows step.
|
||||||
function selectByIndex(idx, { scroll = true } = {}) {
|
function selectByIndex(idx, { scroll = true } = {}) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user