]> git.r.bdr.sh - rbdr/lissajous/blob - lib/factories/ui.js
167c618a0ffe96dbb86a31491ea9ac08c1031410
[rbdr/lissajous] / lib / factories / ui.js
1 /**
2 * This file is a factory for DOM UI elements.
3 */
4
5 /**
6 * Returns a settings container that includes a section and a heading.
7 */
8 export function settingsContainer({id, label, level=2}) {
9
10 const container = document.createElement('section');
11 container.id = id;
12 container.innerHTML = `<h${level}>${label}</h${level}>`;
13 return container;
14 };
15
16 /**
17 * Returns a slider that includes a label, and can optionally be set to
18 * "shift" to a different step. (eg. we use this for π mode, where frequency
19 * and amplitude are mapped to π/8 increments.
20 */
21 export function slider({
22 id,
23 min,
24 max,
25 step,
26 shiftStep,
27 get,
28 set,
29 label = '',
30 className
31 }) {
32
33 const sliderContainer = document.createElement('section');
34 sliderContainer.classList.add('slider');
35 sliderContainer.classList.add(className);
36 const labelElement = document.createElement('label');
37 labelElement.setAttribute('for', id);
38 labelElement.innerHTML = label;
39 const slider = document.createElement('input');
40 slider.id = id;
41 slider.type = 'range';
42 slider.min = min;
43 slider.max = max;
44 slider.step = step;
45 slider.value = get().toString();
46
47 if (shiftStep) {
48 document.addEventListener('keydown', function(event) {
49 if (event.shiftKey) {
50 slider.classList.add('shifted');
51 slider.step = shiftStep;
52 }
53 });
54
55 document.addEventListener('keyup', function(event) {
56 if (event.key === 'Shift') {
57 slider.classList.remove('shifted');
58 slider.step = step;
59 }
60 });
61
62 document.addEventListener('touchstart', function(event) {
63 if (event.touches.length == 3) {
64 if (slider.classList.contains('shifted')) {
65 slider.classList.remove('shifted');
66 slider.step = step;
67 } else {
68 slider.classList.add('shifted');
69 slider.step = shiftStep;
70 }
71 }
72 });
73 }
74
75 slider.addEventListener('input', () => set(slider.value));
76
77 sliderContainer.appendChild(labelElement);
78 sliderContainer.appendChild(slider);
79 return sliderContainer;
80 }