mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
refactor(ui): extract application shortcuts and parameter controls
This commit is contained in:
1 parent
5fa8db1686
commit
7a5f615d55
14 files changed
+469
-92
No files matched your search
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Own generated parameter rows and their input listeners.
|
||||
* The caller supplies uniform metadata/value access and rendering/persistence
|
||||
* callbacks. Replacing or destroying rows revokes all old input handlers.
|
||||
* @param {object} options
|
||||
* @param {HTMLElement} options.container Container owned by this component.
|
||||
* @param {Document} [options.documentRef] Document used to construct rows.
|
||||
* @returns {{render: Function, clear: Function, destroy: Function}}
|
||||
*/
|
||||
export function createStyleParameters({ container, documentRef = container.ownerDocument }) {
|
||||
let listeners = [];
|
||||
let destroyed = false;
|
||||
const clear = () => {
|
||||
if (destroyed) return;
|
||||
for (const [slider, listener] of listeners) slider.removeEventListener('input', listener);
|
||||
listeners = [];
|
||||
container.replaceChildren();
|
||||
};
|
||||
return {
|
||||
/** Render uniform metadata with readValue, writeValue and onChange callbacks. */
|
||||
render({ uniforms, readValue, writeValue, onChange }) {
|
||||
if (destroyed) return;
|
||||
clear();
|
||||
for (const [name, metadata] of Object.entries(uniforms)) {
|
||||
const row = documentRef.createElement('div');
|
||||
row.className = 'param-slider-row';
|
||||
const label = documentRef.createElement('span');
|
||||
label.className = 'param-label';
|
||||
label.textContent = metadata.label;
|
||||
const slider = documentRef.createElement('input');
|
||||
slider.type = 'range';
|
||||
slider.className = 'param-slider';
|
||||
slider.setAttribute('aria-label', metadata.label);
|
||||
slider.min = metadata.min;
|
||||
slider.max = metadata.max;
|
||||
slider.step = metadata.max <= 1 ? '0.01' : '0.1';
|
||||
slider.value = readValue(name);
|
||||
const digits = metadata.max <= 1 ? 2 : 1;
|
||||
const valueDisplay = documentRef.createElement('span');
|
||||
valueDisplay.className = 'param-value';
|
||||
valueDisplay.textContent = parseFloat(slider.value).toFixed(digits);
|
||||
const onInput = () => {
|
||||
const value = parseFloat(slider.value);
|
||||
writeValue(name, value);
|
||||
valueDisplay.textContent = value.toFixed(digits);
|
||||
onChange();
|
||||
};
|
||||
slider.addEventListener('input', onInput);
|
||||
listeners.push([slider, onInput]);
|
||||
row.append(label, slider, valueDisplay);
|
||||
container.appendChild(row);
|
||||
}
|
||||
},
|
||||
clear,
|
||||
destroy() {
|
||||
if (destroyed) return;
|
||||
clear();
|
||||
destroyed = true;
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user