@digitalmeadow/control-panel 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/ControlPanel.d.ts +0 -1
- package/dist/ControlPanel.d.ts.map +1 -1
- package/dist/controllers/Controller.d.ts +1 -0
- package/dist/controllers/Controller.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +787 -313
- package/dist/index.umd.cjs +279 -1
- package/dist/signals/AudioSignals.d.ts +2 -2
- package/dist/signals/MathSignals.d.ts +28 -0
- package/dist/signals/MathSignals.d.ts.map +1 -0
- package/dist/signals/SignalHandler.d.ts +3 -0
- package/dist/signals/SignalHandler.d.ts.map +1 -1
- package/dist/styles.d.ts +2 -0
- package/dist/styles.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/index.css +0 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,297 @@
|
|
|
1
|
+
const z = `
|
|
2
|
+
.cp-root {
|
|
3
|
+
position: fixed;
|
|
4
|
+
top: 10px;
|
|
5
|
+
right: 10px;
|
|
6
|
+
width: 280px;
|
|
7
|
+
max-height: 90vh;
|
|
8
|
+
overflow: auto;
|
|
9
|
+
background: transparent;
|
|
10
|
+
color: #fff;
|
|
11
|
+
mix-blend-mode: exclusion;
|
|
12
|
+
font-family:
|
|
13
|
+
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
|
|
14
|
+
sans-serif;
|
|
15
|
+
font-size: 10px;
|
|
16
|
+
line-height: 1.2;
|
|
17
|
+
padding: 8px;
|
|
18
|
+
z-index: 100;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.cp-root::-webkit-scrollbar {
|
|
22
|
+
width: 1px;
|
|
23
|
+
}
|
|
24
|
+
.cp-root::-webkit-scrollbar-track {
|
|
25
|
+
background: transparent;
|
|
26
|
+
}
|
|
27
|
+
.cp-root::-webkit-scrollbar-thumb {
|
|
28
|
+
background: rgba(255, 255, 255, 0.5);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.cp-summary {
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
user-select: none;
|
|
34
|
+
font-weight: bold;
|
|
35
|
+
outline: none;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.cp-summary-root {
|
|
39
|
+
position: sticky;
|
|
40
|
+
top: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.cp-stats {
|
|
44
|
+
float: right;
|
|
45
|
+
font-weight: normal;
|
|
46
|
+
opacity: 0.6;
|
|
47
|
+
font-size: 0.9em;
|
|
48
|
+
font-variant-numeric: tabular-nums;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.cp-content {
|
|
52
|
+
margin-top: 4px;
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
gap: 6px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.cp-folder {
|
|
59
|
+
width: 100%;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.cp-folder-content {
|
|
63
|
+
margin: 0 0 6px 0;
|
|
64
|
+
padding: 4px 0 0 9px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.cp-controller {
|
|
68
|
+
display: flex;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.cp-label {
|
|
72
|
+
margin: auto 0;
|
|
73
|
+
width: 50%;
|
|
74
|
+
flex-shrink: 0;
|
|
75
|
+
overflow: hidden;
|
|
76
|
+
text-overflow: ellipsis;
|
|
77
|
+
white-space: nowrap;
|
|
78
|
+
user-select: none;
|
|
79
|
+
padding-right: 8px;
|
|
80
|
+
opacity: 0.8;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.cp-input-number {
|
|
84
|
+
width: 50%;
|
|
85
|
+
background: transparent;
|
|
86
|
+
border: 1px solid #fff;
|
|
87
|
+
color: inherit;
|
|
88
|
+
padding: 2px 4px;
|
|
89
|
+
border-radius: 2px;
|
|
90
|
+
font-family: inherit;
|
|
91
|
+
font-size: inherit;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.cp-input-number:focus {
|
|
95
|
+
outline: none;
|
|
96
|
+
border-color: #fff;
|
|
97
|
+
background: transparent;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.cp-select {
|
|
101
|
+
width: 50%;
|
|
102
|
+
background: rgba(255, 255, 255, 0.3);
|
|
103
|
+
border: none;
|
|
104
|
+
padding: 2px 4px;
|
|
105
|
+
border-radius: 2px;
|
|
106
|
+
font-family: inherit;
|
|
107
|
+
font-size: inherit;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.cp-checkbox {
|
|
111
|
+
margin: auto 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.cp-button {
|
|
115
|
+
width: 100%;
|
|
116
|
+
background: rgba(255, 255, 255, 0.3);
|
|
117
|
+
border: none;
|
|
118
|
+
padding: 4px 2px;
|
|
119
|
+
border-radius: 2px;
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
text-align: center;
|
|
122
|
+
font-family: inherit;
|
|
123
|
+
font-size: inherit;
|
|
124
|
+
transition: background 0.1s;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.cp-button:hover {
|
|
128
|
+
background: rgba(255, 255, 255, 0.4);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.cp-button:active {
|
|
132
|
+
background: rgba(255, 255, 255, 0.2);
|
|
133
|
+
transform: translateY(1px);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.cp-controller[data-disabled="true"] {
|
|
137
|
+
opacity: 0.5;
|
|
138
|
+
pointer-events: none;
|
|
139
|
+
cursor: not-allowed;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.cp-controller-details {
|
|
143
|
+
width: 50%;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.cp-controller-summary {
|
|
147
|
+
cursor: pointer;
|
|
148
|
+
outline: none;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.cp-controller-summary-content {
|
|
152
|
+
display: inline-flex;
|
|
153
|
+
align-items: center;
|
|
154
|
+
gap: 6px;
|
|
155
|
+
width: calc(100% - 16px);
|
|
156
|
+
vertical-align: middle;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.cp-input-range {
|
|
160
|
+
-webkit-appearance: none;
|
|
161
|
+
flex: 1;
|
|
162
|
+
min-width: 0;
|
|
163
|
+
height: 2px;
|
|
164
|
+
background: rgba(255, 255, 255, 0.3);
|
|
165
|
+
margin: 0;
|
|
166
|
+
vertical-align: middle;
|
|
167
|
+
cursor: grab;
|
|
168
|
+
}
|
|
169
|
+
.cp-input-range::-webkit-slider-thumb {
|
|
170
|
+
-webkit-appearance: none;
|
|
171
|
+
width: 4px;
|
|
172
|
+
height: 8px;
|
|
173
|
+
border-radius: 1px;
|
|
174
|
+
background: #fff;
|
|
175
|
+
cursor: grab;
|
|
176
|
+
}
|
|
177
|
+
.cp-input-range::-moz-range-thumb {
|
|
178
|
+
width: 4px;
|
|
179
|
+
height: 16px;
|
|
180
|
+
background: #fff;
|
|
181
|
+
cursor: grab;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.cp-input-range:active {
|
|
185
|
+
cursor: grabbing;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.cp-value-display {
|
|
189
|
+
min-width: 24px;
|
|
190
|
+
text-align: right;
|
|
191
|
+
font-variant-numeric: tabular-nums;
|
|
192
|
+
font-size: 0.9em;
|
|
193
|
+
opacity: 0.8;
|
|
194
|
+
user-select: none;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.cp-number-settings {
|
|
198
|
+
margin-top: 4px;
|
|
199
|
+
background: transparent;
|
|
200
|
+
display: flex;
|
|
201
|
+
flex-direction: column;
|
|
202
|
+
gap: 4px;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.cp-separator {
|
|
206
|
+
border: none;
|
|
207
|
+
border-top: 1px solid rgba(255, 255, 255, 0.3);
|
|
208
|
+
margin: 4px 0;
|
|
209
|
+
width: 100%;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.cp-setting-row {
|
|
213
|
+
display: flex;
|
|
214
|
+
align-items: center;
|
|
215
|
+
gap: 4px;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.cp-setting-label {
|
|
219
|
+
width: 50%;
|
|
220
|
+
font-size: 0.9em;
|
|
221
|
+
opacity: 0.7;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.cp-input-small {
|
|
225
|
+
width: 50%;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.cp-radios {
|
|
229
|
+
width: 50%;
|
|
230
|
+
display: flex;
|
|
231
|
+
gap: 2px;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.cp-radio {
|
|
235
|
+
flex: 1;
|
|
236
|
+
font-size: 0.9em;
|
|
237
|
+
padding: 4px 2px;
|
|
238
|
+
height: 100%;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.cp-radio[data-active="true"] {
|
|
242
|
+
background: rgba(255, 255, 255, 0.2);
|
|
243
|
+
border-color: #fff;
|
|
244
|
+
font-weight: bold;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.cp-button-delete {
|
|
248
|
+
width: 24px;
|
|
249
|
+
padding: 0;
|
|
250
|
+
display: flex;
|
|
251
|
+
align-items: center;
|
|
252
|
+
justify-content: center;
|
|
253
|
+
line-height: 1;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.cp-input-color {
|
|
257
|
+
padding: 0;
|
|
258
|
+
margin: 0;
|
|
259
|
+
border: none;
|
|
260
|
+
background: none;
|
|
261
|
+
outline: none;
|
|
262
|
+
|
|
263
|
+
isolation: isolate;
|
|
264
|
+
mix-blend-mode: normal;
|
|
265
|
+
cursor: pointer;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.cp-color-swatch {
|
|
269
|
+
width: 10px;
|
|
270
|
+
height: 10px;
|
|
271
|
+
margin-right: 8px;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.cp-stops-container {
|
|
275
|
+
display: flex;
|
|
276
|
+
flex-direction: column;
|
|
277
|
+
gap: 4px;
|
|
278
|
+
}
|
|
279
|
+
`;
|
|
280
|
+
let V = !1;
|
|
281
|
+
function R() {
|
|
282
|
+
if (V) return;
|
|
283
|
+
const n = document.createElement("style");
|
|
284
|
+
n.id = "control-panel-styles", n.textContent = z, document.head.appendChild(n), V = !0;
|
|
285
|
+
}
|
|
1
286
|
function r(n, t = {}, e = []) {
|
|
2
|
-
const
|
|
3
|
-
for (const [
|
|
4
|
-
|
|
5
|
-
for (const
|
|
6
|
-
typeof
|
|
7
|
-
return
|
|
8
|
-
}
|
|
9
|
-
function
|
|
287
|
+
const s = document.createElement(n);
|
|
288
|
+
for (const [i, a] of Object.entries(t))
|
|
289
|
+
i === "className" ? s.className = String(a) : i === "style" && typeof a == "object" ? Object.assign(s.style, a) : i === "open" && typeof a == "boolean" ? a ? s.setAttribute("open", "") : s.removeAttribute("open") : typeof a != "object" && s.setAttribute(i, String(a));
|
|
290
|
+
for (const i of e)
|
|
291
|
+
typeof i == "string" ? s.appendChild(document.createTextNode(i)) : s.appendChild(i);
|
|
292
|
+
return s;
|
|
293
|
+
}
|
|
294
|
+
function D(n) {
|
|
10
295
|
const t = r(
|
|
11
296
|
"button",
|
|
12
297
|
{
|
|
@@ -16,39 +301,39 @@ function B(n) {
|
|
|
16
301
|
);
|
|
17
302
|
return t.addEventListener("click", n), t;
|
|
18
303
|
}
|
|
19
|
-
function
|
|
304
|
+
function j(n) {
|
|
20
305
|
return n.replace(/([A-Z])/g, " $1").replace(/^./, (t) => t.toUpperCase()).trim();
|
|
21
306
|
}
|
|
22
|
-
function
|
|
307
|
+
function O(n, t, e) {
|
|
23
308
|
return Math.min(Math.max(n, t), e);
|
|
24
309
|
}
|
|
25
|
-
function
|
|
310
|
+
function $(n, t, e) {
|
|
26
311
|
if (t.length !== e.length)
|
|
27
312
|
throw new Error("Input and output ranges must have the same length");
|
|
28
313
|
if (t.length < 2)
|
|
29
314
|
throw new Error("Input and output ranges must have at least two values");
|
|
30
|
-
let
|
|
31
|
-
for (;
|
|
32
|
-
|
|
33
|
-
if (
|
|
315
|
+
let s = 0;
|
|
316
|
+
for (; s < t.length - 1 && n > t[s + 1]; )
|
|
317
|
+
s++;
|
|
318
|
+
if (s === t.length - 1)
|
|
34
319
|
return e[e.length - 1];
|
|
35
|
-
if (
|
|
320
|
+
if (s === 0 && n < t[0])
|
|
36
321
|
return e[0];
|
|
37
|
-
const
|
|
38
|
-
return (n -
|
|
322
|
+
const i = t[s], a = t[s + 1], o = e[s], c = e[s + 1];
|
|
323
|
+
return (n - i) / (a - i) * (c - o) + o;
|
|
39
324
|
}
|
|
40
|
-
class
|
|
325
|
+
class U {
|
|
41
326
|
constructor() {
|
|
42
|
-
this.source = null, this.stream = null, this.fftSize = 2048, this.smoothingTimeConstant = 0.
|
|
327
|
+
this.source = null, this.stream = null, this.fftSize = 2048, this.smoothingTimeConstant = 0.82, this.spectrumBoost = 3, this.levels = {
|
|
328
|
+
volume: 0,
|
|
43
329
|
bass: 0,
|
|
44
330
|
mids: 0,
|
|
45
|
-
highs: 0
|
|
46
|
-
volume: 0
|
|
331
|
+
highs: 0
|
|
47
332
|
}, this.peaks = {
|
|
333
|
+
volume: 0,
|
|
48
334
|
bass: 0,
|
|
49
335
|
mids: 0,
|
|
50
|
-
highs: 0
|
|
51
|
-
volume: 0
|
|
336
|
+
highs: 0
|
|
52
337
|
}, this._isAnalyzing = !1, this.loop = () => {
|
|
53
338
|
this._isAnalyzing && (requestAnimationFrame(this.loop), this.update());
|
|
54
339
|
};
|
|
@@ -67,8 +352,8 @@ class z {
|
|
|
67
352
|
}) : e = navigator.mediaDevices.getUserMedia({
|
|
68
353
|
audio: !0
|
|
69
354
|
});
|
|
70
|
-
const
|
|
71
|
-
this.ctx.state === "suspended" && this.ctx.resume(), this.source && this.source.disconnect(), this.stream && this.stream.getTracks().forEach((
|
|
355
|
+
const s = await e;
|
|
356
|
+
this.ctx.state === "suspended" && this.ctx.resume(), this.source && this.source.disconnect(), this.stream && this.stream.getTracks().forEach((i) => i.stop()), this.stream = s, this.source = this.ctx.createMediaStreamSource(this.stream), this.source.connect(this.analyser), this._isAnalyzing = !0, this.loop();
|
|
72
357
|
} catch (e) {
|
|
73
358
|
console.error("Error accessing audio input:", e), this._isAnalyzing = !1;
|
|
74
359
|
}
|
|
@@ -76,35 +361,35 @@ class z {
|
|
|
76
361
|
update() {
|
|
77
362
|
if (this.analyser.getByteFrequencyData(this.dataArray), this.analyser.getByteTimeDomainData(this.waveformArray), this.spectrumBoost !== 1) {
|
|
78
363
|
const p = this.dataArray.length;
|
|
79
|
-
for (let
|
|
80
|
-
const
|
|
81
|
-
this.dataArray[
|
|
364
|
+
for (let h = 0; h < p; h++) {
|
|
365
|
+
const m = 1 + h / p * (this.spectrumBoost - 1);
|
|
366
|
+
this.dataArray[h] = Math.min(255, this.dataArray[h] * m);
|
|
82
367
|
}
|
|
83
368
|
}
|
|
84
|
-
const t = [2, 10], e = [10, 150],
|
|
85
|
-
this.processLevel("bass",
|
|
369
|
+
const t = [2, 10], e = [10, 150], s = [150, 600], i = this.getAverage(t[0], t[1]), a = this.getAverage(e[0], e[1]), o = this.getAverage(s[0], s[1]), c = this.getAverage(0, s[1]);
|
|
370
|
+
this.processLevel("bass", i), this.processLevel("mids", a), this.processLevel("highs", o), this.processLevel("volume", c);
|
|
86
371
|
}
|
|
87
372
|
processLevel(t, e) {
|
|
88
|
-
this.peaks[t] -= 5e-4, this.peaks[t] =
|
|
89
|
-
|
|
373
|
+
this.peaks[t] -= 5e-4, this.peaks[t] = O(this.peaks[t], 0.1, 1), e > this.peaks[t] && (this.peaks[t] = e), this.levels[t] = O(
|
|
374
|
+
$(e, [0, this.peaks[t]], [0, 1]),
|
|
90
375
|
0,
|
|
91
376
|
1
|
|
92
377
|
);
|
|
93
378
|
}
|
|
94
379
|
getAverage(t, e) {
|
|
95
|
-
let
|
|
96
|
-
const
|
|
97
|
-
if (
|
|
380
|
+
let s = 0;
|
|
381
|
+
const i = e - t;
|
|
382
|
+
if (i <= 0) return 0;
|
|
98
383
|
for (let a = t; a < e; a++)
|
|
99
|
-
|
|
100
|
-
return
|
|
384
|
+
s += this.dataArray[a];
|
|
385
|
+
return s / i / 255;
|
|
101
386
|
}
|
|
102
387
|
getSignal(t) {
|
|
103
388
|
return () => this.levels[t];
|
|
104
389
|
}
|
|
105
390
|
}
|
|
106
|
-
const
|
|
107
|
-
class
|
|
391
|
+
const C = new U();
|
|
392
|
+
class H {
|
|
108
393
|
constructor() {
|
|
109
394
|
this.midiAccess = null, this.values = /* @__PURE__ */ new Map(), this.isListening = !1, this.resolveListen = null, this.listeningCallback = null, this.init();
|
|
110
395
|
}
|
|
@@ -125,18 +410,18 @@ class $ {
|
|
|
125
410
|
e.onmidimessage = this.handleMessage.bind(this);
|
|
126
411
|
}
|
|
127
412
|
handleMessage(t) {
|
|
128
|
-
const e = t.data, [
|
|
129
|
-
if ((
|
|
413
|
+
const e = t.data, [s] = e;
|
|
414
|
+
if ((s & 240) >= 240) return;
|
|
130
415
|
const a = this.getIdFromMessage(t), o = this.normalizeValue(e);
|
|
131
416
|
this.values.set(a, o), this.isListening && this.resolveListen && o > 0 && (this.resolveListen(a), this.isListening = !1, this.resolveListen = null, this.listeningCallback && this.listeningCallback());
|
|
132
417
|
}
|
|
133
418
|
getIdFromMessage(t) {
|
|
134
|
-
const e = t.data, [
|
|
135
|
-
return `${
|
|
419
|
+
const e = t.data, [s, i] = e, a = s & 240, o = t.currentTarget.name || "unknown", c = a === 144 || a === 128 ? "note" : "ctrl", p = o.replace(/[^a-zA-Z0-9]/g, "");
|
|
420
|
+
return `${i}_${c}_${p}`;
|
|
136
421
|
}
|
|
137
422
|
normalizeValue(t) {
|
|
138
|
-
const [e,
|
|
139
|
-
return a === 144 ?
|
|
423
|
+
const [e, s, i] = t, a = e & 240;
|
|
424
|
+
return a === 144 ? i > 0 ? 1 : 0 : a === 128 ? 0 : a === 176 ? i / 127 : 0;
|
|
140
425
|
}
|
|
141
426
|
listen() {
|
|
142
427
|
return this.isListening = !0, new Promise((t) => {
|
|
@@ -150,13 +435,108 @@ class $ {
|
|
|
150
435
|
return () => this.values.get(t) ?? 0;
|
|
151
436
|
}
|
|
152
437
|
}
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
438
|
+
const W = new H();
|
|
439
|
+
class _ {
|
|
440
|
+
constructor() {
|
|
441
|
+
this.configs = /* @__PURE__ */ new Map(), this.lastRandomUpdateTime = 0, this.currentRandomValue = 0, this.startTime = performance.now(), this.configs.set("constant", {
|
|
442
|
+
frequency: 0.1,
|
|
443
|
+
// Units per second
|
|
444
|
+
amplitude: 1,
|
|
445
|
+
offset: 0,
|
|
446
|
+
phase: 0
|
|
447
|
+
}), this.configs.set("sine", {
|
|
448
|
+
frequency: 0.1,
|
|
449
|
+
amplitude: 1,
|
|
450
|
+
offset: 0,
|
|
451
|
+
phase: 0
|
|
452
|
+
}), this.configs.set("sawtooth", {
|
|
453
|
+
frequency: 0.1,
|
|
454
|
+
amplitude: 1,
|
|
455
|
+
offset: 0,
|
|
456
|
+
phase: 0
|
|
457
|
+
}), this.configs.set("triangle", {
|
|
458
|
+
frequency: 0.1,
|
|
459
|
+
amplitude: 1,
|
|
460
|
+
offset: 0,
|
|
461
|
+
phase: 0
|
|
462
|
+
}), this.configs.set("square", {
|
|
463
|
+
frequency: 0.1,
|
|
464
|
+
amplitude: 1,
|
|
465
|
+
offset: 0,
|
|
466
|
+
phase: 0
|
|
467
|
+
}), this.configs.set("random", {
|
|
468
|
+
frequency: 10,
|
|
469
|
+
// Updates per second
|
|
470
|
+
amplitude: 1,
|
|
471
|
+
offset: 0,
|
|
472
|
+
phase: 0
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
setConfig(t, e) {
|
|
476
|
+
const s = this.configs.get(t);
|
|
477
|
+
this.configs.set(t, { ...s, ...e });
|
|
478
|
+
}
|
|
479
|
+
getConfig(t) {
|
|
480
|
+
return { ...this.configs.get(t) };
|
|
481
|
+
}
|
|
482
|
+
getTime() {
|
|
483
|
+
return (performance.now() - this.startTime) / 1e3;
|
|
484
|
+
}
|
|
485
|
+
normalizeOutput(t, e) {
|
|
486
|
+
const s = t * e.amplitude + e.offset;
|
|
487
|
+
return Math.max(0, Math.min(1, s));
|
|
488
|
+
}
|
|
489
|
+
constant(t) {
|
|
490
|
+
const e = t ? { ...this.configs.get("constant"), ...t } : this.configs.get("constant"), i = this.getTime() * e.frequency % 1;
|
|
491
|
+
return this.normalizeOutput(i, e);
|
|
492
|
+
}
|
|
493
|
+
sine(t) {
|
|
494
|
+
const e = t ? { ...this.configs.get("sine"), ...t } : this.configs.get("sine"), s = this.getTime(), i = e.phase * Math.PI * 2, o = (Math.sin(s * e.frequency * Math.PI * 2 + i) + 1) / 2;
|
|
495
|
+
return this.normalizeOutput(o, e);
|
|
496
|
+
}
|
|
497
|
+
sawtooth(t) {
|
|
498
|
+
const e = t ? { ...this.configs.get("sawtooth"), ...t } : this.configs.get("sawtooth"), s = this.getTime(), i = e.phase, a = (s * e.frequency + i) % 1 + i % 1;
|
|
499
|
+
return this.normalizeOutput(a % 1, e);
|
|
500
|
+
}
|
|
501
|
+
triangle(t) {
|
|
502
|
+
const e = t ? { ...this.configs.get("triangle"), ...t } : this.configs.get("triangle"), s = this.getTime(), i = e.phase, a = (s * e.frequency + i) % 1, o = a < 0.5 ? a * 2 : 2 - a * 2;
|
|
503
|
+
return this.normalizeOutput(o, e);
|
|
504
|
+
}
|
|
505
|
+
square(t) {
|
|
506
|
+
const e = t ? { ...this.configs.get("square"), ...t } : this.configs.get("square"), s = this.getTime(), i = e.phase, o = (s * e.frequency + i) % 1 < 0.5 ? 0 : 1;
|
|
507
|
+
return this.normalizeOutput(o, e);
|
|
508
|
+
}
|
|
509
|
+
random(t) {
|
|
510
|
+
const e = t ? { ...this.configs.get("random"), ...t } : this.configs.get("random"), s = performance.now(), i = 1e3 / e.frequency;
|
|
511
|
+
return s - this.lastRandomUpdateTime > i && (this.currentRandomValue = Math.random(), this.lastRandomUpdateTime = s), this.normalizeOutput(this.currentRandomValue, e);
|
|
512
|
+
}
|
|
513
|
+
getSignal(t) {
|
|
514
|
+
switch (t) {
|
|
515
|
+
case "constant":
|
|
516
|
+
return () => this.constant();
|
|
517
|
+
case "sine":
|
|
518
|
+
return () => this.sine();
|
|
519
|
+
case "sawtooth":
|
|
520
|
+
return () => this.sawtooth();
|
|
521
|
+
case "triangle":
|
|
522
|
+
return () => this.triangle();
|
|
523
|
+
case "square":
|
|
524
|
+
return () => this.square();
|
|
525
|
+
case "random":
|
|
526
|
+
return () => this.random();
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
reset() {
|
|
530
|
+
this.startTime = performance.now(), this.lastRandomUpdateTime = 0, this.currentRandomValue = 0;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
const J = new _(), T = class T {
|
|
534
|
+
constructor(t, e, s = {}) {
|
|
535
|
+
this.changeFns = /* @__PURE__ */ new Set(), this.object = t, this.property = e, this.key = s.id ?? e, this.initialValue = this.object[this.property], this.domElement = r("div", { className: "cp-controller" });
|
|
536
|
+
const i = s.label ?? j(e), a = r("label", { className: "cp-label" }, [
|
|
537
|
+
String(i)
|
|
158
538
|
]);
|
|
159
|
-
a.setAttribute("title", String(
|
|
539
|
+
a.setAttribute("title", String(i)), this.domElement.appendChild(a), s.disabled && this.domElement.setAttribute("data-disabled", "true");
|
|
160
540
|
}
|
|
161
541
|
get value() {
|
|
162
542
|
return this.object[this.property];
|
|
@@ -184,9 +564,9 @@ const q = new $(), M = class M {
|
|
|
184
564
|
this.domElement.appendChild(t);
|
|
185
565
|
}
|
|
186
566
|
};
|
|
187
|
-
|
|
188
|
-
let
|
|
189
|
-
const
|
|
567
|
+
T.audio = C, T.midi = W, T.math = J;
|
|
568
|
+
let d = T;
|
|
569
|
+
const P = {
|
|
190
570
|
linear: (n) => n,
|
|
191
571
|
quadIn: (n) => n * n,
|
|
192
572
|
quadOut: (n) => n * (2 - n),
|
|
@@ -201,28 +581,52 @@ const O = {
|
|
|
201
581
|
sineOut: (n) => Math.sin(n * Math.PI / 2),
|
|
202
582
|
sineInOut: (n) => -(Math.cos(Math.PI * n) - 1) / 2
|
|
203
583
|
};
|
|
204
|
-
class
|
|
584
|
+
class B {
|
|
205
585
|
constructor(t) {
|
|
206
586
|
this.rafId = null, this.currentSignalType = null, this.currentMidiId = null, this.currentEase = "linear", this.currentBehaviour = "forward", this.loop = () => {
|
|
207
587
|
if (this.currentSignalType) {
|
|
208
588
|
let e = 0;
|
|
209
|
-
this.currentSignalType === "midi" ? this.currentMidiId && (e =
|
|
210
|
-
|
|
211
|
-
|
|
589
|
+
this.currentSignalType === "midi" ? this.currentMidiId && (e = d.midi.getSignal(this.currentMidiId)()) : [
|
|
590
|
+
"constant",
|
|
591
|
+
"sine",
|
|
592
|
+
"sawtooth",
|
|
593
|
+
"triangle",
|
|
594
|
+
"square",
|
|
595
|
+
"random"
|
|
596
|
+
].includes(this.currentSignalType) ? e = d.math.getSignal(
|
|
597
|
+
this.currentSignalType
|
|
598
|
+
)() : ["volume", "bass", "mids", "highs"].includes(this.currentSignalType) && (e = d.audio.getSignal(
|
|
599
|
+
this.currentSignalType
|
|
600
|
+
)());
|
|
601
|
+
const s = P[this.currentEase](e);
|
|
602
|
+
this.onChange(s, this.currentBehaviour), this.rafId = requestAnimationFrame(this.loop);
|
|
212
603
|
}
|
|
213
604
|
}, this.onChange = t.onChange, this.setupControllers(t.container);
|
|
214
605
|
}
|
|
215
606
|
setupControllers(t) {
|
|
216
607
|
const e = this.createSettingSelect(
|
|
217
608
|
"signal",
|
|
218
|
-
[
|
|
609
|
+
[
|
|
610
|
+
"none",
|
|
611
|
+
"volume",
|
|
612
|
+
"bass",
|
|
613
|
+
"mids",
|
|
614
|
+
"highs",
|
|
615
|
+
"constant",
|
|
616
|
+
"sine",
|
|
617
|
+
"sawtooth",
|
|
618
|
+
"triangle",
|
|
619
|
+
"square",
|
|
620
|
+
"random",
|
|
621
|
+
"midi"
|
|
622
|
+
],
|
|
219
623
|
(o) => this.setSignalType(o)
|
|
220
624
|
);
|
|
221
625
|
this.signalSelect = e.select, t.appendChild(e.row), this.midiRow = r("div", {
|
|
222
626
|
className: "cp-setting-row",
|
|
223
627
|
style: "display: none;"
|
|
224
628
|
});
|
|
225
|
-
const
|
|
629
|
+
const s = r(
|
|
226
630
|
"label",
|
|
227
631
|
{ className: "cp-setting-label" },
|
|
228
632
|
["Midi"]
|
|
@@ -233,44 +637,112 @@ class P {
|
|
|
233
637
|
["Learn"]
|
|
234
638
|
), this.midiBtn.addEventListener("click", async () => {
|
|
235
639
|
if (this.midiBtn.textContent === "Listening...") {
|
|
236
|
-
|
|
640
|
+
d.midi.cancelListen(), this.setMidiId(null);
|
|
237
641
|
return;
|
|
238
642
|
}
|
|
239
643
|
this.midiBtn.textContent = "Listening...";
|
|
240
|
-
const o = await
|
|
644
|
+
const o = await d.midi.listen();
|
|
241
645
|
this.setMidiId(o);
|
|
242
|
-
}), this.midiRow.appendChild(
|
|
243
|
-
|
|
646
|
+
}), this.midiRow.appendChild(s), this.midiRow.appendChild(this.midiBtn), t.appendChild(this.midiRow), this.mathParamsContainer = r("div", {
|
|
647
|
+
style: "display: none; flex-direction: column; gap: 4px;"
|
|
648
|
+
}), t.appendChild(this.mathParamsContainer);
|
|
649
|
+
const i = this.createSettingSelect(
|
|
244
650
|
"behaviour",
|
|
245
651
|
["forward", "backward", "loopForward", "loopBackward", "pingpong"],
|
|
246
652
|
(o) => this.setBehaviour(o)
|
|
247
653
|
);
|
|
248
|
-
this.behaviourRow =
|
|
654
|
+
this.behaviourRow = i.row, this.behaviourSelect = i.select, this.behaviourRow.style.display = "none", this.behaviourSelect.value = this.currentBehaviour, t.appendChild(this.behaviourRow);
|
|
249
655
|
const a = this.createSettingSelect(
|
|
250
656
|
"ease",
|
|
251
|
-
Object.keys(
|
|
657
|
+
Object.keys(P),
|
|
252
658
|
(o) => this.setEase(o)
|
|
253
659
|
);
|
|
254
660
|
this.easeRow = a.row, this.easeSelect = a.select, this.easeRow.style.display = "none", this.easeSelect.value = this.currentEase, t.appendChild(this.easeRow);
|
|
255
661
|
}
|
|
256
|
-
createSettingSelect(t, e,
|
|
257
|
-
const
|
|
662
|
+
createSettingSelect(t, e, s) {
|
|
663
|
+
const i = r("div", { className: "cp-setting-row" }), a = r("label", { className: "cp-setting-label" }, [
|
|
258
664
|
t
|
|
259
665
|
]), o = r("select", {
|
|
260
666
|
className: "cp-select cp-input-small"
|
|
261
667
|
});
|
|
262
|
-
return e.forEach((
|
|
263
|
-
const p = r("option", { value:
|
|
668
|
+
return e.forEach((c) => {
|
|
669
|
+
const p = r("option", { value: c }, [c]);
|
|
264
670
|
o.appendChild(p);
|
|
265
|
-
}), o.addEventListener("change", () =>
|
|
671
|
+
}), o.addEventListener("change", () => s(o.value)), i.appendChild(a), i.appendChild(o), { row: i, select: o };
|
|
672
|
+
}
|
|
673
|
+
createNumberInput(t, e, s, i, a, o) {
|
|
674
|
+
const c = r("div", { className: "cp-setting-row" }), p = r("label", { className: "cp-setting-label" }, [
|
|
675
|
+
t
|
|
676
|
+
]), h = r("input", {
|
|
677
|
+
className: "cp-input-number cp-input-small",
|
|
678
|
+
type: "number",
|
|
679
|
+
value: String(e),
|
|
680
|
+
min: String(s),
|
|
681
|
+
max: String(i),
|
|
682
|
+
step: String(a)
|
|
683
|
+
});
|
|
684
|
+
return h.addEventListener("input", () => {
|
|
685
|
+
const u = parseFloat(h.value);
|
|
686
|
+
isNaN(u) || o(u);
|
|
687
|
+
}), c.appendChild(p), c.appendChild(h), { row: c, input: h };
|
|
688
|
+
}
|
|
689
|
+
updateMathParams(t) {
|
|
690
|
+
this.mathParamsContainer.innerHTML = "";
|
|
691
|
+
const e = d.math.getConfig(t);
|
|
692
|
+
let s = "Frequency", i = 0.1, a = 10, o = 0.1;
|
|
693
|
+
t === "random" ? a = 30 : t === "constant" && (s = "Speed", i = 0.01, a = 2, o = 0.01);
|
|
694
|
+
const c = this.createNumberInput(
|
|
695
|
+
s,
|
|
696
|
+
e.frequency,
|
|
697
|
+
i,
|
|
698
|
+
a,
|
|
699
|
+
o,
|
|
700
|
+
(u) => d.math.setConfig(t, { frequency: u })
|
|
701
|
+
);
|
|
702
|
+
this.mathParamsContainer.appendChild(c.row);
|
|
703
|
+
const p = this.createNumberInput(
|
|
704
|
+
"Amplitude",
|
|
705
|
+
e.amplitude,
|
|
706
|
+
0,
|
|
707
|
+
2,
|
|
708
|
+
0.1,
|
|
709
|
+
(u) => d.math.setConfig(t, { amplitude: u })
|
|
710
|
+
);
|
|
711
|
+
this.mathParamsContainer.appendChild(p.row);
|
|
712
|
+
const h = this.createNumberInput(
|
|
713
|
+
"Offset",
|
|
714
|
+
e.offset,
|
|
715
|
+
0,
|
|
716
|
+
1,
|
|
717
|
+
0.1,
|
|
718
|
+
(u) => d.math.setConfig(t, { offset: u })
|
|
719
|
+
);
|
|
720
|
+
if (this.mathParamsContainer.appendChild(h.row), ["sine", "sawtooth", "triangle", "square"].includes(t)) {
|
|
721
|
+
const u = this.createNumberInput(
|
|
722
|
+
"Phase",
|
|
723
|
+
e.phase,
|
|
724
|
+
0,
|
|
725
|
+
1,
|
|
726
|
+
0.01,
|
|
727
|
+
(m) => d.math.setConfig(t, { phase: m })
|
|
728
|
+
);
|
|
729
|
+
this.mathParamsContainer.appendChild(u.row);
|
|
730
|
+
}
|
|
266
731
|
}
|
|
267
732
|
setSignalType(t) {
|
|
268
733
|
if (!t || t === "none")
|
|
269
|
-
this.currentSignalType = null, this.currentMidiId = null, this.midiRow.style.display = "none", this.easeRow.style.display = "none", this.behaviourRow.style.display = "none", this.stop(), this.signalSelect.value !== "none" && (this.signalSelect.value = "none");
|
|
734
|
+
this.currentSignalType = null, this.currentMidiId = null, this.midiRow.style.display = "none", this.mathParamsContainer.style.display = "none", this.easeRow.style.display = "none", this.behaviourRow.style.display = "none", this.stop(), this.signalSelect.value !== "none" && (this.signalSelect.value = "none");
|
|
270
735
|
else {
|
|
271
736
|
this.currentSignalType = t;
|
|
272
|
-
const e = t === "midi"
|
|
273
|
-
|
|
737
|
+
const e = t === "midi", s = [
|
|
738
|
+
"constant",
|
|
739
|
+
"sine",
|
|
740
|
+
"sawtooth",
|
|
741
|
+
"triangle",
|
|
742
|
+
"square",
|
|
743
|
+
"random"
|
|
744
|
+
].includes(t), i = ["volume", "bass", "mids", "highs"].includes(t);
|
|
745
|
+
this.midiRow.style.display = e ? "flex" : "none", this.mathParamsContainer.style.display = s ? "flex" : "none", s && this.updateMathParams(t), this.easeRow.style.display = "flex", this.behaviourRow.style.display = "flex", i ? (this.currentMidiId = null, d.audio.ctx.state === "suspended" && d.audio.setInput("microphone")) : e || (this.currentMidiId = null), this.start(), this.signalSelect.value !== t && (this.signalSelect.value = t);
|
|
274
746
|
}
|
|
275
747
|
}
|
|
276
748
|
setMidiId(t) {
|
|
@@ -303,10 +775,10 @@ class P {
|
|
|
303
775
|
this.setSignalType("none"), this.setEase("linear"), this.setBehaviour("forward"), this.setMidiId(null);
|
|
304
776
|
}
|
|
305
777
|
}
|
|
306
|
-
class
|
|
307
|
-
constructor(t, e,
|
|
308
|
-
super(t, e,
|
|
309
|
-
const
|
|
778
|
+
class G extends d {
|
|
779
|
+
constructor(t, e, s = {}) {
|
|
780
|
+
super(t, e, s), this.pingPongDirection = 1, this.min = 0, this.max = 100, this.initialOptions = s, this.min = s.min ?? 0, this.max = s.max ?? 100;
|
|
781
|
+
const i = r("details", {
|
|
310
782
|
className: "cp-controller-details"
|
|
311
783
|
}), a = r("summary", {
|
|
312
784
|
className: "cp-controller-summary"
|
|
@@ -314,8 +786,8 @@ class H extends m {
|
|
|
314
786
|
this.input = r("input", {
|
|
315
787
|
type: "range",
|
|
316
788
|
className: "cp-input-range",
|
|
317
|
-
step:
|
|
318
|
-
}),
|
|
789
|
+
step: s.step ?? "any"
|
|
790
|
+
}), s.min !== void 0 && (this.input.min = String(s.min)), s.max !== void 0 && (this.input.max = String(s.max)), this.input.value = String(this.value), this.display = r(
|
|
319
791
|
"span",
|
|
320
792
|
{
|
|
321
793
|
className: "cp-value-display"
|
|
@@ -330,30 +802,30 @@ class H extends m {
|
|
|
330
802
|
const o = r("div", {
|
|
331
803
|
className: "cp-controller-summary-content"
|
|
332
804
|
});
|
|
333
|
-
o.appendChild(this.input), o.appendChild(this.display), a.appendChild(o),
|
|
334
|
-
const
|
|
805
|
+
o.appendChild(this.input), o.appendChild(this.display), a.appendChild(o), i.appendChild(a);
|
|
806
|
+
const c = r("div", { className: "cp-number-settings" }), p = this.createSetting(
|
|
335
807
|
"min",
|
|
336
|
-
|
|
808
|
+
s.min,
|
|
337
809
|
(l) => this.setMin(l)
|
|
338
810
|
);
|
|
339
|
-
this.minInput = p.input,
|
|
340
|
-
const
|
|
811
|
+
this.minInput = p.input, c.appendChild(p.row);
|
|
812
|
+
const h = this.createSetting(
|
|
341
813
|
"max",
|
|
342
|
-
|
|
814
|
+
s.max,
|
|
343
815
|
(l) => this.setMax(l)
|
|
344
816
|
);
|
|
345
|
-
this.maxInput =
|
|
346
|
-
const
|
|
817
|
+
this.maxInput = h.input, c.appendChild(h.row);
|
|
818
|
+
const u = this.createSetting(
|
|
347
819
|
"step",
|
|
348
|
-
|
|
820
|
+
s.step,
|
|
349
821
|
(l) => this.setStep(l)
|
|
350
822
|
);
|
|
351
|
-
this.stepInput =
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
container:
|
|
355
|
-
onChange: (l,
|
|
356
|
-
}),
|
|
823
|
+
this.stepInput = u.input, c.appendChild(u.row);
|
|
824
|
+
const m = r("hr", { className: "cp-separator" });
|
|
825
|
+
c.appendChild(m), this.signalHandler = new B({
|
|
826
|
+
container: c,
|
|
827
|
+
onChange: (l, f) => this.applySignal(l, f)
|
|
828
|
+
}), i.appendChild(c), this.appendWidget(i);
|
|
357
829
|
}
|
|
358
830
|
// Setters
|
|
359
831
|
setMin(t) {
|
|
@@ -366,34 +838,34 @@ class H extends m {
|
|
|
366
838
|
t === void 0 && (t = ""), typeof t == "number" && (t = String(t)), t === "" || t === "any" || isNaN(parseFloat(t)) ? this.input.step = "any" : this.input.step = t, this.stepInput && (t === "any" || t === "" ? this.stepInput.value = "" : this.stepInput.value !== t && (this.stepInput.value = t));
|
|
367
839
|
}
|
|
368
840
|
applySignal(t, e) {
|
|
369
|
-
const
|
|
370
|
-
let
|
|
841
|
+
const s = this.max - this.min;
|
|
842
|
+
let i;
|
|
371
843
|
if (e === "forward")
|
|
372
|
-
|
|
844
|
+
i = this.min + t * s;
|
|
373
845
|
else if (e === "backward")
|
|
374
|
-
|
|
846
|
+
i = this.max - t * s;
|
|
375
847
|
else {
|
|
376
|
-
const a = t * (
|
|
377
|
-
|
|
848
|
+
const a = t * (s * 0.01);
|
|
849
|
+
i = this.value, e === "loopForward" ? (i += a, i > this.max && (i = this.min + (i - this.min) % s)) : e === "loopBackward" ? (i -= a, i < this.min && (i = this.max - (this.max - i) % s)) : e === "pingpong" && (i += a * this.pingPongDirection, i >= this.max ? (i = this.max, this.pingPongDirection = -1) : i <= this.min && (i = this.min, this.pingPongDirection = 1));
|
|
378
850
|
}
|
|
379
|
-
|
|
851
|
+
i = this.roundToStep(i), this.setValue(i), this.input.value = String(i), this.display.textContent = String(i.toFixed(1));
|
|
380
852
|
}
|
|
381
853
|
roundToStep(t) {
|
|
382
854
|
const e = this.input.step;
|
|
383
855
|
if (e === "any" || e === "" || isNaN(parseFloat(e)))
|
|
384
856
|
return t;
|
|
385
|
-
const
|
|
386
|
-
return
|
|
857
|
+
const s = parseFloat(e), i = this.min;
|
|
858
|
+
return i + Math.round((t - i) / s) * s;
|
|
387
859
|
}
|
|
388
|
-
createSetting(t, e,
|
|
389
|
-
const
|
|
860
|
+
createSetting(t, e, s) {
|
|
861
|
+
const i = r("div", { className: "cp-setting-row" }), a = r("label", { className: "cp-setting-label" }, [
|
|
390
862
|
t
|
|
391
863
|
]), o = r("input", {
|
|
392
864
|
type: "number",
|
|
393
865
|
className: "cp-input-number cp-input-small",
|
|
394
866
|
step: "any"
|
|
395
867
|
});
|
|
396
|
-
return e !== void 0 && (o.value = String(e)), o.addEventListener("input", () =>
|
|
868
|
+
return e !== void 0 && (o.value = String(e)), o.addEventListener("input", () => s(o.value)), i.appendChild(a), i.appendChild(o), { row: i, input: o };
|
|
397
869
|
}
|
|
398
870
|
updateDisplay() {
|
|
399
871
|
this.input.value = String(this.value), this.display.textContent = String(this.value.toFixed(1));
|
|
@@ -419,8 +891,8 @@ class H extends m {
|
|
|
419
891
|
), e.max !== void 0 ? this.setMax(e.max) : this.setMax(
|
|
420
892
|
this.initialOptions.max !== void 0 ? this.initialOptions.max : ""
|
|
421
893
|
), e.step !== void 0 ? this.setStep(e.step) : this.setStep(this.initialOptions.step);
|
|
422
|
-
let
|
|
423
|
-
!isNaN(this.min) &&
|
|
894
|
+
let s = t.value;
|
|
895
|
+
!isNaN(this.min) && s < this.min && (s = this.min), !isNaN(this.max) && s > this.max && (s = this.max), this.setValue(s), this.signalHandler?.load(e.signal);
|
|
424
896
|
}
|
|
425
897
|
}
|
|
426
898
|
reset() {
|
|
@@ -434,24 +906,24 @@ class H extends m {
|
|
|
434
906
|
), this.setStep(this.initialOptions.step), this.signalHandler?.reset();
|
|
435
907
|
}
|
|
436
908
|
}
|
|
437
|
-
class
|
|
438
|
-
constructor(t, e,
|
|
439
|
-
super(t, e,
|
|
909
|
+
class Z extends d {
|
|
910
|
+
constructor(t, e, s) {
|
|
911
|
+
super(t, e, s), this.optionValues = [], this.select = r("select", { className: "cp-select" }), this.optionValues = s.options || [], this.optionValues.forEach((i, a) => {
|
|
440
912
|
const o = r("option", { value: String(a) }, [
|
|
441
|
-
String(
|
|
913
|
+
String(i)
|
|
442
914
|
]);
|
|
443
915
|
this.select.appendChild(o);
|
|
444
916
|
}), this.updateDisplay(), this.select.addEventListener("change", () => {
|
|
445
|
-
const
|
|
917
|
+
const i = parseInt(this.select.value), a = this.optionValues[i];
|
|
446
918
|
this.setValue(a);
|
|
447
919
|
}), this.appendWidget(this.select);
|
|
448
920
|
}
|
|
449
921
|
setOptions(t) {
|
|
450
|
-
this.select.innerHTML = "", this.optionValues = t, this.optionValues.forEach((e,
|
|
451
|
-
const
|
|
922
|
+
this.select.innerHTML = "", this.optionValues = t, this.optionValues.forEach((e, s) => {
|
|
923
|
+
const i = r("option", { value: String(s) }, [
|
|
452
924
|
String(e)
|
|
453
925
|
]);
|
|
454
|
-
this.select.appendChild(
|
|
926
|
+
this.select.appendChild(i);
|
|
455
927
|
}), this.updateDisplay(), this.select.value === "" && this.optionValues.length > 0 && this.setValue(this.optionValues[0]);
|
|
456
928
|
}
|
|
457
929
|
updateDisplay() {
|
|
@@ -459,11 +931,11 @@ class U extends m {
|
|
|
459
931
|
t !== -1 && (this.select.value = String(t));
|
|
460
932
|
}
|
|
461
933
|
}
|
|
462
|
-
class
|
|
463
|
-
constructor(t, e,
|
|
464
|
-
const
|
|
465
|
-
super(
|
|
466
|
-
const a =
|
|
934
|
+
class K extends d {
|
|
935
|
+
constructor(t, e, s = {}) {
|
|
936
|
+
const i = { action: e };
|
|
937
|
+
super(i, "action", s);
|
|
938
|
+
const a = s.label ?? t;
|
|
467
939
|
this.button = r("button", { className: "cp-button" }, [
|
|
468
940
|
String(a)
|
|
469
941
|
]), this.button.addEventListener("click", () => {
|
|
@@ -474,9 +946,9 @@ class _ extends m {
|
|
|
474
946
|
updateDisplay() {
|
|
475
947
|
}
|
|
476
948
|
}
|
|
477
|
-
class
|
|
478
|
-
constructor(t, e,
|
|
479
|
-
super(t, e,
|
|
949
|
+
class Y extends d {
|
|
950
|
+
constructor(t, e, s = {}) {
|
|
951
|
+
super(t, e, s), this.input = r("input", {
|
|
480
952
|
type: "checkbox",
|
|
481
953
|
className: "cp-checkbox"
|
|
482
954
|
}), this.input.checked = this.value, this.input.addEventListener("change", () => {
|
|
@@ -487,32 +959,32 @@ class W extends m {
|
|
|
487
959
|
this.input.checked = this.value;
|
|
488
960
|
}
|
|
489
961
|
}
|
|
490
|
-
class
|
|
491
|
-
constructor(t, e,
|
|
492
|
-
super(t, e,
|
|
962
|
+
class Q extends d {
|
|
963
|
+
constructor(t, e, s) {
|
|
964
|
+
super(t, e, s), this.buttons = [], this.optionValues = [], this.container = r("div", { className: "cp-radios" }), this.optionValues = s.options || [], this.optionValues.forEach((i) => {
|
|
493
965
|
const a = r("button", { className: "cp-button cp-radio" }, [
|
|
494
|
-
String(
|
|
966
|
+
String(i)
|
|
495
967
|
]);
|
|
496
968
|
a.addEventListener("click", () => {
|
|
497
|
-
this.setValue(
|
|
969
|
+
this.setValue(i);
|
|
498
970
|
}), this.container.appendChild(a), this.buttons.push(a);
|
|
499
971
|
}), this.updateDisplay(), this.appendWidget(this.container);
|
|
500
972
|
}
|
|
501
973
|
updateDisplay() {
|
|
502
974
|
const t = this.value;
|
|
503
|
-
this.buttons.forEach((e,
|
|
504
|
-
this.optionValues[
|
|
975
|
+
this.buttons.forEach((e, s) => {
|
|
976
|
+
this.optionValues[s] === t ? e.setAttribute("data-active", "true") : e.removeAttribute("data-active");
|
|
505
977
|
});
|
|
506
978
|
}
|
|
507
979
|
}
|
|
508
|
-
class
|
|
509
|
-
constructor(t, e,
|
|
510
|
-
super(t, e,
|
|
980
|
+
class X extends d {
|
|
981
|
+
constructor(t, e, s = {}) {
|
|
982
|
+
super(t, e, s), this.input = r("input", {
|
|
511
983
|
type: "color",
|
|
512
984
|
className: "cp-input-color",
|
|
513
985
|
value: this.value || "#000000"
|
|
514
|
-
}), this.appendWidget(this.input), this.input.addEventListener("input", (
|
|
515
|
-
const a =
|
|
986
|
+
}), this.appendWidget(this.input), this.input.addEventListener("input", (i) => {
|
|
987
|
+
const a = i.target;
|
|
516
988
|
this.setValue(a.value);
|
|
517
989
|
}), this.updateDisplay();
|
|
518
990
|
}
|
|
@@ -522,7 +994,7 @@ class G extends m {
|
|
|
522
994
|
}
|
|
523
995
|
function F(n) {
|
|
524
996
|
const t = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
|
525
|
-
n = n.replace(t, (
|
|
997
|
+
n = n.replace(t, (s, i, a, o) => i + i + a + a + o + o);
|
|
526
998
|
const e = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(n);
|
|
527
999
|
return e ? [
|
|
528
1000
|
parseInt(e[1], 16),
|
|
@@ -530,27 +1002,27 @@ function F(n) {
|
|
|
530
1002
|
parseInt(e[3], 16)
|
|
531
1003
|
] : [0, 0, 0];
|
|
532
1004
|
}
|
|
533
|
-
function
|
|
1005
|
+
function tt(n, t, e) {
|
|
534
1006
|
return "#" + ((1 << 24) + (Math.round(n) << 16) + (Math.round(t) << 8) + Math.round(e)).toString(16).slice(1);
|
|
535
1007
|
}
|
|
536
1008
|
function w(n) {
|
|
537
1009
|
const t = n / 255;
|
|
538
1010
|
return t <= 0.04045 ? t / 12.92 : Math.pow((t + 0.055) / 1.055, 2.4);
|
|
539
1011
|
}
|
|
540
|
-
function
|
|
1012
|
+
function L(n) {
|
|
541
1013
|
return n <= 31308e-7 ? n * 12.92 * 255 : (1.055 * Math.pow(n, 1 / 2.4) - 0.055) * 255;
|
|
542
1014
|
}
|
|
543
|
-
function
|
|
544
|
-
const [
|
|
545
|
-
return
|
|
1015
|
+
function et(n, t, e) {
|
|
1016
|
+
const [s, i, a] = F(n), [o, c, p] = F(t), h = w(s), u = w(i), m = w(a), l = w(o), f = w(c), g = w(p), b = h + e * (l - h), I = u + e * (f - u), v = m + e * (g - m), S = L(b), y = L(I), x = L(v);
|
|
1017
|
+
return tt(S, y, x);
|
|
546
1018
|
}
|
|
547
|
-
class
|
|
548
|
-
constructor(t, e,
|
|
549
|
-
super(t, e,
|
|
1019
|
+
class st extends d {
|
|
1020
|
+
constructor(t, e, s = {}) {
|
|
1021
|
+
super(t, e, s), this.stops = [], this.pingPongDirection = 1, this.animationT = 0, this.manualPosition = 0, this.initialOptions = s, this.stops = s.stops || [
|
|
550
1022
|
{ color: "#000000", position: 0 },
|
|
551
1023
|
{ color: "#ffffff", position: 1 }
|
|
552
1024
|
], this.sortStops();
|
|
553
|
-
const
|
|
1025
|
+
const i = r("details", {
|
|
554
1026
|
className: "cp-controller-details"
|
|
555
1027
|
}), a = r("summary", {
|
|
556
1028
|
className: "cp-controller-summary"
|
|
@@ -564,11 +1036,11 @@ class Q extends m {
|
|
|
564
1036
|
"span",
|
|
565
1037
|
{ className: "cp-value-display" },
|
|
566
1038
|
[String(this.value)]
|
|
567
|
-
), o.appendChild(this.displayColor), o.appendChild(this.displayText), a.appendChild(o),
|
|
568
|
-
const
|
|
1039
|
+
), o.appendChild(this.displayColor), o.appendChild(this.displayText), a.appendChild(o), i.appendChild(a);
|
|
1040
|
+
const c = r("div", { className: "cp-number-settings" });
|
|
569
1041
|
this.stopsContainer = r("div", {
|
|
570
1042
|
className: "cp-stops-container"
|
|
571
|
-
}), this.renderStops(),
|
|
1043
|
+
}), this.renderStops(), c.appendChild(this.stopsContainer);
|
|
572
1044
|
const p = r(
|
|
573
1045
|
"button",
|
|
574
1046
|
{
|
|
@@ -578,25 +1050,25 @@ class Q extends m {
|
|
|
578
1050
|
);
|
|
579
1051
|
p.addEventListener("click", () => {
|
|
580
1052
|
this.stops.push({ color: "#ffffff", position: 0.5 }), this.sortStops(), this.renderStops(), this.updateOutput();
|
|
581
|
-
}),
|
|
582
|
-
const
|
|
583
|
-
|
|
584
|
-
container:
|
|
585
|
-
onChange: (
|
|
586
|
-
}),
|
|
1053
|
+
}), c.appendChild(p);
|
|
1054
|
+
const h = r("hr", { className: "cp-separator" });
|
|
1055
|
+
c.appendChild(h), this.signalHandler = new B({
|
|
1056
|
+
container: c,
|
|
1057
|
+
onChange: (u, m) => this.applySignal(u, m)
|
|
1058
|
+
}), i.appendChild(c), this.appendWidget(i), this.updateOutput(0);
|
|
587
1059
|
}
|
|
588
1060
|
sortStops() {
|
|
589
1061
|
this.stops.sort((t, e) => t.position - e.position);
|
|
590
1062
|
}
|
|
591
1063
|
renderStops() {
|
|
592
1064
|
this.stopsContainer.innerHTML = "", this.stops.forEach((t, e) => {
|
|
593
|
-
const
|
|
1065
|
+
const s = r("div", { className: "cp-setting-row" }), i = r("input", {
|
|
594
1066
|
type: "color",
|
|
595
1067
|
className: "cp-input-color",
|
|
596
1068
|
value: t.color
|
|
597
1069
|
});
|
|
598
|
-
|
|
599
|
-
t.color =
|
|
1070
|
+
i.addEventListener("input", (c) => {
|
|
1071
|
+
t.color = c.target.value, this.updateOutput();
|
|
600
1072
|
});
|
|
601
1073
|
const a = r("input", {
|
|
602
1074
|
type: "number",
|
|
@@ -606,14 +1078,14 @@ class Q extends m {
|
|
|
606
1078
|
step: "0.01",
|
|
607
1079
|
value: String(t.position)
|
|
608
1080
|
});
|
|
609
|
-
a.addEventListener("change", (
|
|
610
|
-
let p = parseFloat(
|
|
1081
|
+
a.addEventListener("change", (c) => {
|
|
1082
|
+
let p = parseFloat(c.target.value);
|
|
611
1083
|
isNaN(p) && (p = 0), t.position = Math.max(0, Math.min(1, p)), this.sortStops(), this.renderStops(), this.updateOutput();
|
|
612
1084
|
});
|
|
613
|
-
const o =
|
|
1085
|
+
const o = D(() => {
|
|
614
1086
|
this.stops.splice(e, 1), this.renderStops(), this.updateOutput();
|
|
615
1087
|
});
|
|
616
|
-
|
|
1088
|
+
s.appendChild(i), s.appendChild(a), s.appendChild(o), this.stopsContainer.appendChild(s);
|
|
617
1089
|
});
|
|
618
1090
|
}
|
|
619
1091
|
// Calculate color at t (0-1) and update value
|
|
@@ -629,11 +1101,11 @@ class Q extends m {
|
|
|
629
1101
|
else if (t >= this.stops[this.stops.length - 1].position)
|
|
630
1102
|
e = this.stops[this.stops.length - 1].color;
|
|
631
1103
|
else
|
|
632
|
-
for (let
|
|
633
|
-
const
|
|
634
|
-
if (t >=
|
|
635
|
-
const o = a.position -
|
|
636
|
-
e =
|
|
1104
|
+
for (let s = 0; s < this.stops.length - 1; s++) {
|
|
1105
|
+
const i = this.stops[s], a = this.stops[s + 1];
|
|
1106
|
+
if (t >= i.position && t <= a.position) {
|
|
1107
|
+
const o = a.position - i.position, c = o === 0 ? 0 : (t - i.position) / o;
|
|
1108
|
+
e = et(i.color, a.color, c);
|
|
637
1109
|
break;
|
|
638
1110
|
}
|
|
639
1111
|
}
|
|
@@ -643,16 +1115,16 @@ class Q extends m {
|
|
|
643
1115
|
this.displayColor && (this.displayColor.style.backgroundColor = this.value), this.displayText && (this.displayText.textContent = this.value);
|
|
644
1116
|
}
|
|
645
1117
|
applySignal(t, e) {
|
|
646
|
-
let
|
|
1118
|
+
let s = t;
|
|
647
1119
|
if (e === "forward")
|
|
648
|
-
|
|
1120
|
+
s = t;
|
|
649
1121
|
else if (e === "backward")
|
|
650
|
-
|
|
1122
|
+
s = 1 - t;
|
|
651
1123
|
else {
|
|
652
|
-
const
|
|
653
|
-
e === "loopForward" ? (this.animationT = (this.animationT +
|
|
1124
|
+
const i = t * 0.05;
|
|
1125
|
+
e === "loopForward" ? (this.animationT = (this.animationT + i) % 1, s = this.animationT) : e === "loopBackward" ? (this.animationT = (this.animationT - i + 1) % 1, s = this.animationT) : e === "pingpong" && (this.animationT += i * this.pingPongDirection, this.animationT >= 1 ? (this.animationT = 1, this.pingPongDirection = -1) : this.animationT <= 0 && (this.animationT = 0, this.pingPongDirection = 1), s = this.animationT);
|
|
654
1126
|
}
|
|
655
|
-
this.updateOutput(
|
|
1127
|
+
this.updateOutput(s), this.manualPosition = s;
|
|
656
1128
|
}
|
|
657
1129
|
save() {
|
|
658
1130
|
return {
|
|
@@ -672,24 +1144,24 @@ class Q extends m {
|
|
|
672
1144
|
], this.sortStops(), this.renderStops(), this.signalHandler?.reset(), this.updateOutput(0);
|
|
673
1145
|
}
|
|
674
1146
|
}
|
|
675
|
-
class
|
|
676
|
-
constructor(t, e,
|
|
677
|
-
super(t, e,
|
|
678
|
-
const
|
|
1147
|
+
class it extends d {
|
|
1148
|
+
constructor(t, e, s = {}) {
|
|
1149
|
+
super(t, e, s), this.items = [], this.initialOptions = s, this.itemType = s.itemType || "string", this.items = this.parseValue(this.value);
|
|
1150
|
+
const i = r("details", {
|
|
679
1151
|
className: "cp-controller-details"
|
|
680
1152
|
}), a = r("summary", {
|
|
681
1153
|
className: "cp-controller-summary"
|
|
682
1154
|
}), o = r("div", {
|
|
683
1155
|
className: "cp-controller-summary-content"
|
|
684
|
-
}),
|
|
1156
|
+
}), c = r("span", { className: "cp-value-display" }, [
|
|
685
1157
|
`${this.items.length} items`
|
|
686
1158
|
]);
|
|
687
|
-
o.appendChild(
|
|
1159
|
+
o.appendChild(c), a.appendChild(o), i.appendChild(a);
|
|
688
1160
|
const p = r("div", { className: "cp-number-settings" });
|
|
689
1161
|
this.itemsContainer = r("div", {
|
|
690
1162
|
className: "cp-stops-container"
|
|
691
1163
|
}), this.renderItems(), p.appendChild(this.itemsContainer);
|
|
692
|
-
const
|
|
1164
|
+
const h = r(
|
|
693
1165
|
"button",
|
|
694
1166
|
{
|
|
695
1167
|
className: "cp-button cp-input-small",
|
|
@@ -697,9 +1169,9 @@ class X extends m {
|
|
|
697
1169
|
},
|
|
698
1170
|
["+ Add Item"]
|
|
699
1171
|
);
|
|
700
|
-
|
|
1172
|
+
h.addEventListener("click", () => {
|
|
701
1173
|
this.addItem();
|
|
702
|
-
}), p.appendChild(
|
|
1174
|
+
}), p.appendChild(h), i.appendChild(p), this.appendWidget(i);
|
|
703
1175
|
}
|
|
704
1176
|
parseValue(t) {
|
|
705
1177
|
return !t || t.trim() === "" ? [] : t.split(",").map((e) => e.trim());
|
|
@@ -731,28 +1203,28 @@ class X extends m {
|
|
|
731
1203
|
}
|
|
732
1204
|
renderItems() {
|
|
733
1205
|
this.itemsContainer.innerHTML = "", this.items.forEach((t, e) => {
|
|
734
|
-
const
|
|
735
|
-
let
|
|
736
|
-
this.itemType === "color" ?
|
|
1206
|
+
const s = r("div", { className: "cp-setting-row" });
|
|
1207
|
+
let i;
|
|
1208
|
+
this.itemType === "color" ? i = r("input", {
|
|
737
1209
|
type: "color",
|
|
738
1210
|
className: "cp-input-color",
|
|
739
1211
|
value: t
|
|
740
|
-
}) : this.itemType === "number" ?
|
|
1212
|
+
}) : this.itemType === "number" ? i = r("input", {
|
|
741
1213
|
type: "number",
|
|
742
1214
|
className: "cp-input-number cp-input-small",
|
|
743
1215
|
step: "any",
|
|
744
1216
|
value: t
|
|
745
|
-
}) :
|
|
1217
|
+
}) : i = r("input", {
|
|
746
1218
|
type: "text",
|
|
747
1219
|
className: "cp-input-number cp-input-small",
|
|
748
1220
|
value: t
|
|
749
|
-
}),
|
|
1221
|
+
}), i.addEventListener("input", (o) => {
|
|
750
1222
|
this.items[e] = o.target.value, this.updateValue();
|
|
751
1223
|
});
|
|
752
|
-
const a =
|
|
1224
|
+
const a = D(() => {
|
|
753
1225
|
this.items.splice(e, 1), this.renderItems(), this.updateValue();
|
|
754
1226
|
});
|
|
755
|
-
|
|
1227
|
+
s.appendChild(i), s.appendChild(a), this.itemsContainer.appendChild(s);
|
|
756
1228
|
});
|
|
757
1229
|
}
|
|
758
1230
|
updateDisplay() {
|
|
@@ -768,16 +1240,16 @@ class X extends m {
|
|
|
768
1240
|
this.items = this.parseValue(t), this.renderItems(), this.updateValue();
|
|
769
1241
|
}
|
|
770
1242
|
}
|
|
771
|
-
class
|
|
1243
|
+
class nt {
|
|
772
1244
|
constructor() {
|
|
773
1245
|
this.frames = 0, this.pollingInterval = 1e3, this.prevTime = performance.now(), this.render = () => {
|
|
774
1246
|
this.frames++;
|
|
775
1247
|
const t = performance.now();
|
|
776
1248
|
if (t >= this.prevTime + this.pollingInterval) {
|
|
777
1249
|
const e = Math.round(this.frames * 1e3 / (t - this.prevTime));
|
|
778
|
-
let
|
|
779
|
-
const
|
|
780
|
-
|
|
1250
|
+
let s = "";
|
|
1251
|
+
const i = performance.memory;
|
|
1252
|
+
i && (s = ` / ${Math.round(i.usedJSHeapSize / 1048576)}MB`), this.domElement.textContent = `${e} FPS${s}`, this.prevTime = t, this.frames = 0;
|
|
781
1253
|
}
|
|
782
1254
|
this.rafId = requestAnimationFrame(this.render);
|
|
783
1255
|
}, this.domElement = r("span", { className: "cp-stats" }), this.rafId = requestAnimationFrame(this.render);
|
|
@@ -786,44 +1258,44 @@ class Y {
|
|
|
786
1258
|
cancelAnimationFrame(this.rafId);
|
|
787
1259
|
}
|
|
788
1260
|
}
|
|
789
|
-
class
|
|
1261
|
+
class q {
|
|
790
1262
|
constructor() {
|
|
791
1263
|
this.controllers = [], this.folders = [];
|
|
792
1264
|
}
|
|
793
|
-
addNumber(t, e,
|
|
794
|
-
const
|
|
795
|
-
return this.contentElement.appendChild(
|
|
1265
|
+
addNumber(t, e, s = {}) {
|
|
1266
|
+
const i = new G(t, e, s);
|
|
1267
|
+
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
796
1268
|
}
|
|
797
|
-
addSelect(t, e,
|
|
798
|
-
const
|
|
799
|
-
return this.contentElement.appendChild(
|
|
1269
|
+
addSelect(t, e, s = {}) {
|
|
1270
|
+
const i = new Z(t, e, s);
|
|
1271
|
+
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
800
1272
|
}
|
|
801
|
-
addBoolean(t, e,
|
|
802
|
-
const
|
|
803
|
-
return this.contentElement.appendChild(
|
|
1273
|
+
addBoolean(t, e, s = {}) {
|
|
1274
|
+
const i = new Y(t, e, s);
|
|
1275
|
+
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
804
1276
|
}
|
|
805
|
-
addButton(t, e,
|
|
806
|
-
const
|
|
807
|
-
return this.contentElement.appendChild(
|
|
1277
|
+
addButton(t, e, s = {}) {
|
|
1278
|
+
const i = new K(t, e, s);
|
|
1279
|
+
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
808
1280
|
}
|
|
809
|
-
addRadio(t, e,
|
|
810
|
-
const
|
|
811
|
-
return this.contentElement.appendChild(
|
|
1281
|
+
addRadio(t, e, s = {}) {
|
|
1282
|
+
const i = new Q(t, e, s);
|
|
1283
|
+
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
812
1284
|
}
|
|
813
|
-
addColor(t, e,
|
|
814
|
-
const
|
|
815
|
-
return this.contentElement.appendChild(
|
|
1285
|
+
addColor(t, e, s = {}) {
|
|
1286
|
+
const i = new X(t, e, s);
|
|
1287
|
+
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
816
1288
|
}
|
|
817
|
-
addGradient(t, e,
|
|
818
|
-
const
|
|
819
|
-
return this.contentElement.appendChild(
|
|
1289
|
+
addGradient(t, e, s = {}) {
|
|
1290
|
+
const i = new st(t, e, s);
|
|
1291
|
+
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
820
1292
|
}
|
|
821
|
-
addArray(t, e,
|
|
822
|
-
const
|
|
823
|
-
return this.contentElement.appendChild(
|
|
1293
|
+
addArray(t, e, s = {}) {
|
|
1294
|
+
const i = new it(t, e, s);
|
|
1295
|
+
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
824
1296
|
}
|
|
825
1297
|
addFolder(t) {
|
|
826
|
-
const e = new
|
|
1298
|
+
const e = new at(t);
|
|
827
1299
|
return this.contentElement.appendChild(e.domElement), this.folders.push(e), e;
|
|
828
1300
|
}
|
|
829
1301
|
save() {
|
|
@@ -845,13 +1317,13 @@ class k {
|
|
|
845
1317
|
for (const e of this.controllers)
|
|
846
1318
|
if (typeof e.value != "function")
|
|
847
1319
|
if (t.controllers && e.key in t.controllers) {
|
|
848
|
-
const
|
|
849
|
-
|
|
1320
|
+
const s = t.controllers[e.key];
|
|
1321
|
+
s !== void 0 && e.load(s);
|
|
850
1322
|
} else
|
|
851
1323
|
e.reset();
|
|
852
1324
|
for (const e of this.folders) {
|
|
853
|
-
const
|
|
854
|
-
e.load(
|
|
1325
|
+
const s = t.folders ? t.folders[e.title] : void 0;
|
|
1326
|
+
e.load(s);
|
|
855
1327
|
}
|
|
856
1328
|
}
|
|
857
1329
|
reset() {
|
|
@@ -861,7 +1333,7 @@ class k {
|
|
|
861
1333
|
t.reset();
|
|
862
1334
|
}
|
|
863
1335
|
}
|
|
864
|
-
class
|
|
1336
|
+
class at extends q {
|
|
865
1337
|
constructor(t) {
|
|
866
1338
|
super(), this.title = t, this.domElement = r("details", {
|
|
867
1339
|
className: "cp-folder",
|
|
@@ -879,40 +1351,40 @@ class tt extends k {
|
|
|
879
1351
|
);
|
|
880
1352
|
}
|
|
881
1353
|
}
|
|
882
|
-
class
|
|
1354
|
+
class ot extends q {
|
|
883
1355
|
constructor(t, e = {}) {
|
|
884
|
-
super(), this.domElement = r("details", {
|
|
1356
|
+
super(), R(), this.domElement = r("details", {
|
|
885
1357
|
className: "cp-root",
|
|
886
1358
|
open: !0
|
|
887
1359
|
}), this.summaryElement = r("summary", {
|
|
888
1360
|
className: "cp-summary cp-summary-root"
|
|
889
1361
|
}), this.domElement.appendChild(this.summaryElement);
|
|
890
|
-
const
|
|
1362
|
+
const s = r("span", {}, [
|
|
891
1363
|
e.title || "ControlPanel"
|
|
892
1364
|
]);
|
|
893
|
-
this.summaryElement.appendChild(
|
|
894
|
-
const
|
|
1365
|
+
this.summaryElement.appendChild(s), this.stats = new nt(), this.summaryElement.appendChild(this.stats.domElement), this.contentElement = r("div", { className: "cp-content" }), this.domElement.appendChild(this.contentElement);
|
|
1366
|
+
const i = this.addFolder("_Signals"), a = {
|
|
895
1367
|
audioInput: null,
|
|
896
1368
|
fftSize: 2048
|
|
897
1369
|
};
|
|
898
|
-
|
|
1370
|
+
i.addRadio(a, "audioInput", {
|
|
899
1371
|
label: "Audio Signal",
|
|
900
1372
|
options: ["microphone", "browser"]
|
|
901
1373
|
}).onChange((l) => {
|
|
902
|
-
|
|
903
|
-
}),
|
|
1374
|
+
C.setInput(l);
|
|
1375
|
+
}), i.addSelect(a, "fftSize", {
|
|
904
1376
|
label: "FFT Size",
|
|
905
1377
|
options: [256, 512, 1024, 2048]
|
|
906
1378
|
}).onChange((l) => {
|
|
907
|
-
|
|
908
|
-
}),
|
|
1379
|
+
C.setFFTSize(l);
|
|
1380
|
+
}), i.addNumber(C, "smoothingTimeConstant", {
|
|
909
1381
|
min: 0,
|
|
910
1382
|
max: 0.99,
|
|
911
1383
|
step: 0.01,
|
|
912
1384
|
label: "Smoothing"
|
|
913
1385
|
}).onChange((l) => {
|
|
914
|
-
|
|
915
|
-
}),
|
|
1386
|
+
C.analyser.smoothingTimeConstant = l;
|
|
1387
|
+
}), i.addNumber(C, "spectrumBoost", {
|
|
916
1388
|
min: 1,
|
|
917
1389
|
max: 5,
|
|
918
1390
|
step: 0.1,
|
|
@@ -920,127 +1392,127 @@ class et extends k {
|
|
|
920
1392
|
}), t ? t.appendChild(this.domElement) : document.body.appendChild(this.domElement);
|
|
921
1393
|
const o = e.title || "ControlPanel";
|
|
922
1394
|
this.presetStoragePrefix = `cp-presets-${o}-`;
|
|
923
|
-
const
|
|
1395
|
+
const c = this.addFolder("_User Presets"), p = () => {
|
|
924
1396
|
const l = ["Default"];
|
|
925
1397
|
if (typeof localStorage > "u") return l;
|
|
926
|
-
for (let
|
|
927
|
-
const
|
|
928
|
-
if (
|
|
929
|
-
const
|
|
930
|
-
|
|
1398
|
+
for (let f = 0; f < localStorage.length; f++) {
|
|
1399
|
+
const g = localStorage.key(f);
|
|
1400
|
+
if (g && g.startsWith(this.presetStoragePrefix)) {
|
|
1401
|
+
const b = g.substring(this.presetStoragePrefix.length);
|
|
1402
|
+
b !== "Default" && !l.includes(b) && l.push(b);
|
|
931
1403
|
}
|
|
932
1404
|
}
|
|
933
1405
|
return l.sort();
|
|
934
|
-
},
|
|
1406
|
+
}, h = {
|
|
935
1407
|
selected: "Default",
|
|
936
1408
|
save: () => {
|
|
937
|
-
const l = prompt("Preset Name:",
|
|
1409
|
+
const l = prompt("Preset Name:", h.selected);
|
|
938
1410
|
if (l) {
|
|
939
1411
|
if (l === "Default") {
|
|
940
1412
|
alert("Cannot overwrite Default preset");
|
|
941
1413
|
return;
|
|
942
1414
|
}
|
|
943
|
-
const
|
|
944
|
-
this.saveToLocalStorage(
|
|
945
|
-
const
|
|
946
|
-
|
|
1415
|
+
const f = this.presetStoragePrefix + l;
|
|
1416
|
+
this.saveToLocalStorage(f);
|
|
1417
|
+
const g = p();
|
|
1418
|
+
m.setOptions(g), h.selected = l, m.setValue(l);
|
|
947
1419
|
}
|
|
948
1420
|
},
|
|
949
1421
|
load: () => {
|
|
950
|
-
const l =
|
|
951
|
-
this.loadFromLocalStorage(
|
|
1422
|
+
const l = h.selected, f = this.presetStoragePrefix + l;
|
|
1423
|
+
this.loadFromLocalStorage(f), h.selected = l, m.setValue(l);
|
|
952
1424
|
},
|
|
953
1425
|
delete: () => {
|
|
954
|
-
if (
|
|
1426
|
+
if (h.selected === "Default") {
|
|
955
1427
|
alert("Cannot delete Default preset");
|
|
956
1428
|
return;
|
|
957
1429
|
}
|
|
958
|
-
if (confirm(`Delete preset "${
|
|
959
|
-
const l = this.presetStoragePrefix +
|
|
1430
|
+
if (confirm(`Delete preset "${h.selected}"?`)) {
|
|
1431
|
+
const l = this.presetStoragePrefix + h.selected;
|
|
960
1432
|
localStorage.removeItem(l);
|
|
961
|
-
const
|
|
962
|
-
|
|
1433
|
+
const f = p();
|
|
1434
|
+
m.setOptions(f), h.selected = "Default", m.setValue("Default"), this.reset();
|
|
963
1435
|
}
|
|
964
1436
|
},
|
|
965
1437
|
export: () => {
|
|
966
|
-
const l = this.save(),
|
|
1438
|
+
const l = this.save(), f = (M) => {
|
|
967
1439
|
const N = {
|
|
968
1440
|
controllers: {},
|
|
969
1441
|
folders: {}
|
|
970
1442
|
};
|
|
971
|
-
for (const [E,
|
|
972
|
-
E.startsWith("_") || (N.controllers[E] =
|
|
973
|
-
for (const [E,
|
|
974
|
-
|
|
1443
|
+
for (const [E, k] of Object.entries(M.controllers))
|
|
1444
|
+
E.startsWith("_") || (N.controllers[E] = k);
|
|
1445
|
+
for (const [E, k] of Object.entries(
|
|
1446
|
+
M.folders
|
|
975
1447
|
))
|
|
976
|
-
E.startsWith("_") || (N.folders[E] =
|
|
1448
|
+
E.startsWith("_") || (N.folders[E] = f(k));
|
|
977
1449
|
return N;
|
|
978
|
-
},
|
|
979
|
-
_presetName:
|
|
1450
|
+
}, g = f(l), b = {
|
|
1451
|
+
_presetName: h.selected || "CustomPreset",
|
|
980
1452
|
_exportDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
981
1453
|
_instructions: "To add as factory preset: Copy 'controllers' and 'folders' fields into the presets.json file",
|
|
982
|
-
...
|
|
983
|
-
}, I = JSON.stringify(
|
|
984
|
-
|
|
985
|
-
const
|
|
986
|
-
|
|
1454
|
+
...g
|
|
1455
|
+
}, I = JSON.stringify(b, null, 2), v = new Blob([I], { type: "application/json" }), S = URL.createObjectURL(v), y = document.createElement("a");
|
|
1456
|
+
y.href = S;
|
|
1457
|
+
const x = (/* @__PURE__ */ new Date()).toISOString().split("T")[0], A = h.selected.replace(/[^a-z0-9]/gi, "-").toLowerCase();
|
|
1458
|
+
y.download = `${o.toLowerCase()}-preset-${A}-${x}.json`, document.body.appendChild(y), y.click(), document.body.removeChild(y), URL.revokeObjectURL(S);
|
|
987
1459
|
},
|
|
988
1460
|
import: () => {
|
|
989
1461
|
const l = document.createElement("input");
|
|
990
|
-
l.type = "file", l.accept = ".json", l.onchange = (
|
|
991
|
-
const
|
|
992
|
-
if (!
|
|
993
|
-
const
|
|
994
|
-
|
|
1462
|
+
l.type = "file", l.accept = ".json", l.onchange = (f) => {
|
|
1463
|
+
const g = f.target.files?.[0];
|
|
1464
|
+
if (!g) return;
|
|
1465
|
+
const b = new FileReader();
|
|
1466
|
+
b.onload = (I) => {
|
|
995
1467
|
try {
|
|
996
|
-
const
|
|
997
|
-
controllers:
|
|
998
|
-
folders:
|
|
1468
|
+
const v = I.target?.result, S = JSON.parse(v), y = {
|
|
1469
|
+
controllers: S.controllers || {},
|
|
1470
|
+
folders: S.folders || {}
|
|
999
1471
|
};
|
|
1000
|
-
if (!
|
|
1472
|
+
if (!y.controllers || !y.folders) {
|
|
1001
1473
|
alert(
|
|
1002
1474
|
"Invalid preset file: missing 'controllers' or 'folders'"
|
|
1003
1475
|
);
|
|
1004
1476
|
return;
|
|
1005
1477
|
}
|
|
1006
|
-
this.load(
|
|
1007
|
-
const
|
|
1478
|
+
this.load(y);
|
|
1479
|
+
const x = S._presetName || "ImportedPreset";
|
|
1008
1480
|
if (confirm(
|
|
1009
|
-
`Preset loaded! Save as "${
|
|
1481
|
+
`Preset loaded! Save as "${x}" to User Presets?`
|
|
1010
1482
|
)) {
|
|
1011
|
-
const
|
|
1012
|
-
this.saveToLocalStorage(
|
|
1483
|
+
const M = this.presetStoragePrefix + x;
|
|
1484
|
+
this.saveToLocalStorage(M);
|
|
1013
1485
|
const N = p();
|
|
1014
|
-
|
|
1486
|
+
m.setOptions(N), h.selected = x, m.setValue(x);
|
|
1015
1487
|
}
|
|
1016
|
-
} catch (
|
|
1488
|
+
} catch (v) {
|
|
1017
1489
|
alert(
|
|
1018
|
-
`Failed to import preset: ${
|
|
1019
|
-
), console.error("Import error:",
|
|
1490
|
+
`Failed to import preset: ${v instanceof Error ? v.message : "Invalid JSON"}`
|
|
1491
|
+
), console.error("Import error:", v);
|
|
1020
1492
|
}
|
|
1021
|
-
},
|
|
1493
|
+
}, b.readAsText(g);
|
|
1022
1494
|
}, l.click();
|
|
1023
1495
|
}
|
|
1024
|
-
},
|
|
1496
|
+
}, u = p(), m = c.addSelect(h, "selected", {
|
|
1025
1497
|
label: "Preset",
|
|
1026
|
-
options:
|
|
1498
|
+
options: u
|
|
1027
1499
|
});
|
|
1028
|
-
|
|
1500
|
+
c.addButton("Load", () => h.load()), c.addButton("Save / New", () => h.save()), c.addButton("Delete", () => h.delete()), c.addButton("Export JSON", () => h.export()), c.addButton("Import JSON", () => h.import());
|
|
1029
1501
|
}
|
|
1030
1502
|
saveToLocalStorage(t) {
|
|
1031
1503
|
const e = this.save();
|
|
1032
1504
|
try {
|
|
1033
1505
|
localStorage.setItem(t, JSON.stringify(e));
|
|
1034
|
-
} catch (
|
|
1035
|
-
console.warn("ControlPanel: Failed to save to localStorage",
|
|
1506
|
+
} catch (s) {
|
|
1507
|
+
console.warn("ControlPanel: Failed to save to localStorage", s);
|
|
1036
1508
|
}
|
|
1037
1509
|
}
|
|
1038
1510
|
loadFromLocalStorage(t) {
|
|
1039
1511
|
try {
|
|
1040
1512
|
const e = localStorage.getItem(t);
|
|
1041
1513
|
if (e) {
|
|
1042
|
-
const
|
|
1043
|
-
this.load(
|
|
1514
|
+
const s = JSON.parse(e);
|
|
1515
|
+
this.load(s);
|
|
1044
1516
|
}
|
|
1045
1517
|
} catch (e) {
|
|
1046
1518
|
console.warn("ControlPanel: Failed to load from localStorage", e);
|
|
@@ -1055,20 +1527,22 @@ class et extends k {
|
|
|
1055
1527
|
}
|
|
1056
1528
|
}
|
|
1057
1529
|
export {
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
H as
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1530
|
+
it as ArrayController,
|
|
1531
|
+
U as AudioSignals,
|
|
1532
|
+
Y as BooleanController,
|
|
1533
|
+
K as ButtonController,
|
|
1534
|
+
X as ColorController,
|
|
1535
|
+
ot as ControlPanel,
|
|
1536
|
+
q as ControlPanelContainer,
|
|
1537
|
+
d as Controller,
|
|
1538
|
+
at as Folder,
|
|
1539
|
+
st as GradientController,
|
|
1540
|
+
_ as MathSignals,
|
|
1541
|
+
H as MidiSignals,
|
|
1542
|
+
G as NumberController,
|
|
1543
|
+
Q as RadioController,
|
|
1544
|
+
Z as SelectController,
|
|
1545
|
+
C as audioSignals,
|
|
1546
|
+
J as mathSignals,
|
|
1547
|
+
W as midiSignals
|
|
1074
1548
|
};
|