/** * This file is a factory for DOM UI elements. */ /** * Returns a settings container that includes a section and a heading. */ export function settingsContainer({id, label, level=2}) { const container = document.createElement('section'); container.id = id; container.innerHTML = `${label}`; return container; }; /** * Returns a slider that includes a label, and can optionally be set to * "shift" to a different step. (eg. we use this for π mode, where frequency * and amplitude are mapped to π/8 increments. */ export function slider({ id, min, max, step, shiftStep, get, set, label = '', className }) { const sliderContainer = document.createElement('section'); sliderContainer.classList.add('slider'); sliderContainer.classList.add(className); const labelElement = document.createElement('label'); labelElement.setAttribute('for', id); labelElement.innerHTML = label; const slider = document.createElement('input'); slider.id = id; slider.type = 'range'; slider.min = min; slider.max = max; slider.step = step; slider.value = get().toString(); if (shiftStep) { document.addEventListener('keydown', function(event) { if (event.shiftKey) { slider.classList.add('shifted'); slider.step = shiftStep; } }); document.addEventListener('keyup', function(event) { if (event.key === 'Shift') { slider.classList.remove('shifted'); slider.step = step; } }); document.addEventListener('touchstart', function(event) { if (event.touches.length == 3) { if (slider.classList.contains('shifted')) { slider.classList.remove('shifted'); slider.step = step; } else { slider.classList.add('shifted'); slider.step = shiftStep; } } }); } slider.addEventListener('input', () => set(slider.value)); sliderContainer.appendChild(labelElement); sliderContainer.appendChild(slider); return sliderContainer; }