]>
Commit | Line | Data |
---|---|---|
32e2eed2 RBR |
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 | */ | |
362f9116 RBR |
8 | export function settingsContainer({id, label, level=2}) { |
9 | ||
6a87c253 | 10 | const container = document.createElement('section'); |
362f9116 RBR |
11 | container.id = id; |
12 | container.innerHTML = `<h${level}>${label}</h${level}>`; | |
13 | return container; | |
14 | }; | |
15 | ||
32e2eed2 RBR |
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 | */ | |
6a87c253 RBR |
21 | export function slider({ |
22 | id, | |
23 | min, | |
24 | max, | |
25 | step, | |
26 | shiftStep, | |
27 | get, | |
28 | set, | |
29 | label = '', | |
30 | className | |
31 | }) { | |
362f9116 | 32 | |
6a87c253 | 33 | const sliderContainer = document.createElement('section'); |
362f9116 RBR |
34 | sliderContainer.classList.add('slider'); |
35 | sliderContainer.classList.add(className); | |
36 | const labelElement = document.createElement('label'); | |
6a87c253 | 37 | labelElement.setAttribute('for', id); |
362f9116 RBR |
38 | labelElement.innerHTML = label; |
39 | const slider = document.createElement('input'); | |
6a87c253 | 40 | slider.id = id; |
362f9116 RBR |
41 | slider.type = 'range'; |
42 | slider.min = min; | |
43 | slider.max = max; | |
44 | slider.step = step; | |
45 | slider.value = get().toString(); | |
46 | ||
6a87c253 RBR |
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 | }); | |
1924acb2 RBR |
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 | }); | |
6a87c253 RBR |
73 | } |
74 | ||
362f9116 RBR |
75 | slider.addEventListener('input', () => set(slider.value)); |
76 | ||
77 | sliderContainer.appendChild(labelElement); | |
78 | sliderContainer.appendChild(slider); | |
79 | return sliderContainer; | |
80 | } |