@digitalmeadow/control-panel 1.0.5 → 1.0.7
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/dist/ControlPanel.d.ts +2 -0
- package/dist/ControlPanel.d.ts.map +1 -1
- package/dist/index.js +310 -242
- package/dist/index.umd.cjs +40 -12
- package/dist/styles.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,25 +1,53 @@
|
|
|
1
|
-
const
|
|
1
|
+
const W = `
|
|
2
2
|
.cp-root {
|
|
3
|
-
position:
|
|
4
|
-
top:
|
|
5
|
-
right:
|
|
6
|
-
width: 280px;
|
|
3
|
+
position: absolute;
|
|
4
|
+
top: 0;
|
|
5
|
+
right: 0;
|
|
6
|
+
width: min(280px, 90%);
|
|
7
7
|
max-height: 90vh;
|
|
8
8
|
overflow: auto;
|
|
9
9
|
background: transparent;
|
|
10
|
+
resize: both;
|
|
10
11
|
color: #fff;
|
|
11
|
-
|
|
12
|
+
min-width: 200px;
|
|
13
|
+
min-height: 50px;
|
|
12
14
|
font-family:
|
|
13
15
|
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
|
|
14
16
|
sans-serif;
|
|
15
17
|
font-size: 10px;
|
|
16
18
|
line-height: 1.2;
|
|
17
19
|
padding: 8px;
|
|
18
|
-
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Apply blend mode to all children except color inputs */
|
|
23
|
+
.cp-root .cp-label,
|
|
24
|
+
.cp-root .cp-setting-label,
|
|
25
|
+
.cp-root .cp-summary,
|
|
26
|
+
.cp-root .cp-controller-summary,
|
|
27
|
+
.cp-root .cp-separator,
|
|
28
|
+
.cp-root .cp-value-display,
|
|
29
|
+
.cp-root .cp-button,
|
|
30
|
+
.cp-root .cp-input-number,
|
|
31
|
+
.cp-root .cp-input-range,
|
|
32
|
+
.cp-root .cp-select,
|
|
33
|
+
.cp-root .cp-radio
|
|
34
|
+
{
|
|
35
|
+
mix-blend-mode: difference;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.cp-root .cp-input-color,
|
|
39
|
+
.cp-root .cp-color-swatch {
|
|
40
|
+
mix-blend-mode: normal;
|
|
41
|
+
isolation: isolate;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.cp-root:not([open]) .cp-summary-root {
|
|
45
|
+
opacity: 0.5;
|
|
19
46
|
}
|
|
20
47
|
|
|
21
48
|
.cp-root::-webkit-scrollbar {
|
|
22
49
|
width: 1px;
|
|
50
|
+
height: 1px;
|
|
23
51
|
}
|
|
24
52
|
.cp-root::-webkit-scrollbar-track {
|
|
25
53
|
background: transparent;
|
|
@@ -38,6 +66,7 @@ const z = `
|
|
|
38
66
|
.cp-summary-root {
|
|
39
67
|
position: sticky;
|
|
40
68
|
top: 0;
|
|
69
|
+
cursor: grab;
|
|
41
70
|
}
|
|
42
71
|
|
|
43
72
|
.cp-stats {
|
|
@@ -83,7 +112,7 @@ const z = `
|
|
|
83
112
|
.cp-input-number {
|
|
84
113
|
width: 50%;
|
|
85
114
|
background: transparent;
|
|
86
|
-
border: 1px solid
|
|
115
|
+
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
87
116
|
color: inherit;
|
|
88
117
|
padding: 2px 4px;
|
|
89
118
|
border-radius: 2px;
|
|
@@ -99,6 +128,7 @@ const z = `
|
|
|
99
128
|
|
|
100
129
|
.cp-select {
|
|
101
130
|
width: 50%;
|
|
131
|
+
color: inherit;
|
|
102
132
|
background: rgba(255, 255, 255, 0.3);
|
|
103
133
|
border: none;
|
|
104
134
|
padding: 2px 4px;
|
|
@@ -113,6 +143,7 @@ const z = `
|
|
|
113
143
|
|
|
114
144
|
.cp-button {
|
|
115
145
|
width: 100%;
|
|
146
|
+
color: inherit;
|
|
116
147
|
background: rgba(255, 255, 255, 0.3);
|
|
117
148
|
border: none;
|
|
118
149
|
padding: 4px 2px;
|
|
@@ -259,9 +290,6 @@ const z = `
|
|
|
259
290
|
border: none;
|
|
260
291
|
background: none;
|
|
261
292
|
outline: none;
|
|
262
|
-
|
|
263
|
-
isolation: isolate;
|
|
264
|
-
mix-blend-mode: normal;
|
|
265
293
|
cursor: pointer;
|
|
266
294
|
}
|
|
267
295
|
|
|
@@ -277,11 +305,11 @@ const z = `
|
|
|
277
305
|
gap: 4px;
|
|
278
306
|
}
|
|
279
307
|
`;
|
|
280
|
-
let
|
|
281
|
-
function
|
|
282
|
-
if (
|
|
308
|
+
let B = !1;
|
|
309
|
+
function _() {
|
|
310
|
+
if (B) return;
|
|
283
311
|
const n = document.createElement("style");
|
|
284
|
-
n.id = "control-panel-styles", n.textContent =
|
|
312
|
+
n.id = "control-panel-styles", n.textContent = W, document.head.appendChild(n), B = !0;
|
|
285
313
|
}
|
|
286
314
|
function r(n, t = {}, e = []) {
|
|
287
315
|
const s = document.createElement(n);
|
|
@@ -291,7 +319,7 @@ function r(n, t = {}, e = []) {
|
|
|
291
319
|
typeof i == "string" ? s.appendChild(document.createTextNode(i)) : s.appendChild(i);
|
|
292
320
|
return s;
|
|
293
321
|
}
|
|
294
|
-
function
|
|
322
|
+
function j(n) {
|
|
295
323
|
const t = r(
|
|
296
324
|
"button",
|
|
297
325
|
{
|
|
@@ -301,13 +329,13 @@ function D(n) {
|
|
|
301
329
|
);
|
|
302
330
|
return t.addEventListener("click", n), t;
|
|
303
331
|
}
|
|
304
|
-
function
|
|
332
|
+
function J(n) {
|
|
305
333
|
return n.replace(/([A-Z])/g, " $1").replace(/^./, (t) => t.toUpperCase()).trim();
|
|
306
334
|
}
|
|
307
|
-
function
|
|
335
|
+
function q(n, t, e) {
|
|
308
336
|
return Math.min(Math.max(n, t), e);
|
|
309
337
|
}
|
|
310
|
-
function
|
|
338
|
+
function Y(n, t, e) {
|
|
311
339
|
if (t.length !== e.length)
|
|
312
340
|
throw new Error("Input and output ranges must have the same length");
|
|
313
341
|
if (t.length < 2)
|
|
@@ -319,10 +347,10 @@ function $(n, t, e) {
|
|
|
319
347
|
return e[e.length - 1];
|
|
320
348
|
if (s === 0 && n < t[0])
|
|
321
349
|
return e[0];
|
|
322
|
-
const i = t[s], a = t[s + 1], o = e[s],
|
|
323
|
-
return (n - i) / (a - i) * (
|
|
350
|
+
const i = t[s], a = t[s + 1], o = e[s], l = e[s + 1];
|
|
351
|
+
return (n - i) / (a - i) * (l - o) + o;
|
|
324
352
|
}
|
|
325
|
-
class
|
|
353
|
+
class X {
|
|
326
354
|
constructor() {
|
|
327
355
|
this.source = null, this.stream = null, this.fftSize = 2048, this.smoothingTimeConstant = 0.82, this.spectrumBoost = 3, this.levels = {
|
|
328
356
|
volume: 0,
|
|
@@ -360,18 +388,18 @@ class U {
|
|
|
360
388
|
}
|
|
361
389
|
update() {
|
|
362
390
|
if (this.analyser.getByteFrequencyData(this.dataArray), this.analyser.getByteTimeDomainData(this.waveformArray), this.spectrumBoost !== 1) {
|
|
363
|
-
const
|
|
364
|
-
for (let
|
|
365
|
-
const
|
|
366
|
-
this.dataArray[
|
|
391
|
+
const h = this.dataArray.length;
|
|
392
|
+
for (let p = 0; p < h; p++) {
|
|
393
|
+
const b = 1 + p / h * (this.spectrumBoost - 1);
|
|
394
|
+
this.dataArray[p] = Math.min(255, this.dataArray[p] * b);
|
|
367
395
|
}
|
|
368
396
|
}
|
|
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]),
|
|
370
|
-
this.processLevel("bass", i), this.processLevel("mids", a), this.processLevel("highs", o), this.processLevel("volume",
|
|
397
|
+
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]), l = this.getAverage(0, s[1]);
|
|
398
|
+
this.processLevel("bass", i), this.processLevel("mids", a), this.processLevel("highs", o), this.processLevel("volume", l);
|
|
371
399
|
}
|
|
372
400
|
processLevel(t, e) {
|
|
373
|
-
this.peaks[t] -= 5e-4, this.peaks[t] =
|
|
374
|
-
|
|
401
|
+
this.peaks[t] -= 5e-4, this.peaks[t] = q(this.peaks[t], 0.1, 1), e > this.peaks[t] && (this.peaks[t] = e), this.levels[t] = q(
|
|
402
|
+
Y(e, [0, this.peaks[t]], [0, 1]),
|
|
375
403
|
0,
|
|
376
404
|
1
|
|
377
405
|
);
|
|
@@ -388,8 +416,8 @@ class U {
|
|
|
388
416
|
return () => this.levels[t];
|
|
389
417
|
}
|
|
390
418
|
}
|
|
391
|
-
const
|
|
392
|
-
class
|
|
419
|
+
const M = new X();
|
|
420
|
+
class G {
|
|
393
421
|
constructor() {
|
|
394
422
|
this.midiAccess = null, this.values = /* @__PURE__ */ new Map(), this.isListening = !1, this.resolveListen = null, this.listeningCallback = null, this.init();
|
|
395
423
|
}
|
|
@@ -416,8 +444,8 @@ class H {
|
|
|
416
444
|
this.values.set(a, o), this.isListening && this.resolveListen && o > 0 && (this.resolveListen(a), this.isListening = !1, this.resolveListen = null, this.listeningCallback && this.listeningCallback());
|
|
417
445
|
}
|
|
418
446
|
getIdFromMessage(t) {
|
|
419
|
-
const e = t.data, [s, i] = e, a = s & 240, o = t.currentTarget.name || "unknown",
|
|
420
|
-
return `${i}_${
|
|
447
|
+
const e = t.data, [s, i] = e, a = s & 240, o = t.currentTarget.name || "unknown", l = a === 144 || a === 128 ? "note" : "ctrl", h = o.replace(/[^a-zA-Z0-9]/g, "");
|
|
448
|
+
return `${i}_${l}_${h}`;
|
|
421
449
|
}
|
|
422
450
|
normalizeValue(t) {
|
|
423
451
|
const [e, s, i] = t, a = e & 240;
|
|
@@ -435,8 +463,8 @@ class H {
|
|
|
435
463
|
return () => this.values.get(t) ?? 0;
|
|
436
464
|
}
|
|
437
465
|
}
|
|
438
|
-
const
|
|
439
|
-
class
|
|
466
|
+
const Z = new G();
|
|
467
|
+
class K {
|
|
440
468
|
constructor() {
|
|
441
469
|
this.configs = /* @__PURE__ */ new Map(), this.lastRandomUpdateTime = 0, this.currentRandomValue = 0, this.startTime = performance.now(), this.configs.set("constant", {
|
|
442
470
|
frequency: 0.1,
|
|
@@ -530,10 +558,10 @@ class _ {
|
|
|
530
558
|
this.startTime = performance.now(), this.lastRandomUpdateTime = 0, this.currentRandomValue = 0;
|
|
531
559
|
}
|
|
532
560
|
}
|
|
533
|
-
const
|
|
561
|
+
const Q = new K(), P = class P {
|
|
534
562
|
constructor(t, e, s = {}) {
|
|
535
563
|
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 ??
|
|
564
|
+
const i = s.label ?? J(e), a = r("label", { className: "cp-label" }, [
|
|
537
565
|
String(i)
|
|
538
566
|
]);
|
|
539
567
|
a.setAttribute("title", String(i)), this.domElement.appendChild(a), s.disabled && this.domElement.setAttribute("data-disabled", "true");
|
|
@@ -564,9 +592,9 @@ const J = new _(), T = class T {
|
|
|
564
592
|
this.domElement.appendChild(t);
|
|
565
593
|
}
|
|
566
594
|
};
|
|
567
|
-
|
|
568
|
-
let
|
|
569
|
-
const
|
|
595
|
+
P.audio = M, P.midi = Z, P.math = Q;
|
|
596
|
+
let u = P;
|
|
597
|
+
const R = {
|
|
570
598
|
linear: (n) => n,
|
|
571
599
|
quadIn: (n) => n * n,
|
|
572
600
|
quadOut: (n) => n * (2 - n),
|
|
@@ -581,24 +609,24 @@ const P = {
|
|
|
581
609
|
sineOut: (n) => Math.sin(n * Math.PI / 2),
|
|
582
610
|
sineInOut: (n) => -(Math.cos(Math.PI * n) - 1) / 2
|
|
583
611
|
};
|
|
584
|
-
class
|
|
612
|
+
class H {
|
|
585
613
|
constructor(t) {
|
|
586
614
|
this.rafId = null, this.currentSignalType = null, this.currentMidiId = null, this.currentEase = "linear", this.currentBehaviour = "forward", this.loop = () => {
|
|
587
615
|
if (this.currentSignalType) {
|
|
588
616
|
let e = 0;
|
|
589
|
-
this.currentSignalType === "midi" ? this.currentMidiId && (e =
|
|
617
|
+
this.currentSignalType === "midi" ? this.currentMidiId && (e = u.midi.getSignal(this.currentMidiId)()) : [
|
|
590
618
|
"constant",
|
|
591
619
|
"sine",
|
|
592
620
|
"sawtooth",
|
|
593
621
|
"triangle",
|
|
594
622
|
"square",
|
|
595
623
|
"random"
|
|
596
|
-
].includes(this.currentSignalType) ? e =
|
|
624
|
+
].includes(this.currentSignalType) ? e = u.math.getSignal(
|
|
597
625
|
this.currentSignalType
|
|
598
|
-
)() : ["volume", "bass", "mids", "highs"].includes(this.currentSignalType) && (e =
|
|
626
|
+
)() : ["volume", "bass", "mids", "highs"].includes(this.currentSignalType) && (e = u.audio.getSignal(
|
|
599
627
|
this.currentSignalType
|
|
600
628
|
)());
|
|
601
|
-
const s =
|
|
629
|
+
const s = R[this.currentEase](e);
|
|
602
630
|
this.onChange(s, this.currentBehaviour), this.rafId = requestAnimationFrame(this.loop);
|
|
603
631
|
}
|
|
604
632
|
}, this.onChange = t.onChange, this.setupControllers(t.container);
|
|
@@ -637,11 +665,11 @@ class B {
|
|
|
637
665
|
["Learn"]
|
|
638
666
|
), this.midiBtn.addEventListener("click", async () => {
|
|
639
667
|
if (this.midiBtn.textContent === "Listening...") {
|
|
640
|
-
|
|
668
|
+
u.midi.cancelListen(), this.setMidiId(null);
|
|
641
669
|
return;
|
|
642
670
|
}
|
|
643
671
|
this.midiBtn.textContent = "Listening...";
|
|
644
|
-
const o = await
|
|
672
|
+
const o = await u.midi.listen();
|
|
645
673
|
this.setMidiId(o);
|
|
646
674
|
}), this.midiRow.appendChild(s), this.midiRow.appendChild(this.midiBtn), t.appendChild(this.midiRow), this.mathParamsContainer = r("div", {
|
|
647
675
|
style: "display: none; flex-direction: column; gap: 4px;"
|
|
@@ -654,7 +682,7 @@ class B {
|
|
|
654
682
|
this.behaviourRow = i.row, this.behaviourSelect = i.select, this.behaviourRow.style.display = "none", this.behaviourSelect.value = this.currentBehaviour, t.appendChild(this.behaviourRow);
|
|
655
683
|
const a = this.createSettingSelect(
|
|
656
684
|
"ease",
|
|
657
|
-
Object.keys(
|
|
685
|
+
Object.keys(R),
|
|
658
686
|
(o) => this.setEase(o)
|
|
659
687
|
);
|
|
660
688
|
this.easeRow = a.row, this.easeSelect = a.select, this.easeRow.style.display = "none", this.easeSelect.value = this.currentEase, t.appendChild(this.easeRow);
|
|
@@ -665,15 +693,15 @@ class B {
|
|
|
665
693
|
]), o = r("select", {
|
|
666
694
|
className: "cp-select cp-input-small"
|
|
667
695
|
});
|
|
668
|
-
return e.forEach((
|
|
669
|
-
const
|
|
670
|
-
o.appendChild(
|
|
696
|
+
return e.forEach((l) => {
|
|
697
|
+
const h = r("option", { value: l }, [l]);
|
|
698
|
+
o.appendChild(h);
|
|
671
699
|
}), o.addEventListener("change", () => s(o.value)), i.appendChild(a), i.appendChild(o), { row: i, select: o };
|
|
672
700
|
}
|
|
673
701
|
createNumberInput(t, e, s, i, a, o) {
|
|
674
|
-
const
|
|
702
|
+
const l = r("div", { className: "cp-setting-row" }), h = r("label", { className: "cp-setting-label" }, [
|
|
675
703
|
t
|
|
676
|
-
]),
|
|
704
|
+
]), p = r("input", {
|
|
677
705
|
className: "cp-input-number cp-input-small",
|
|
678
706
|
type: "number",
|
|
679
707
|
value: String(e),
|
|
@@ -681,52 +709,52 @@ class B {
|
|
|
681
709
|
max: String(i),
|
|
682
710
|
step: String(a)
|
|
683
711
|
});
|
|
684
|
-
return
|
|
685
|
-
const
|
|
686
|
-
isNaN(
|
|
687
|
-
}),
|
|
712
|
+
return p.addEventListener("input", () => {
|
|
713
|
+
const d = parseFloat(p.value);
|
|
714
|
+
isNaN(d) || o(d);
|
|
715
|
+
}), l.appendChild(h), l.appendChild(p), { row: l, input: p };
|
|
688
716
|
}
|
|
689
717
|
updateMathParams(t) {
|
|
690
718
|
this.mathParamsContainer.innerHTML = "";
|
|
691
|
-
const e =
|
|
719
|
+
const e = u.math.getConfig(t);
|
|
692
720
|
let s = "Frequency", i = 0.1, a = 10, o = 0.1;
|
|
693
721
|
t === "random" ? a = 30 : t === "constant" && (s = "Speed", i = 0.01, a = 2, o = 0.01);
|
|
694
|
-
const
|
|
722
|
+
const l = this.createNumberInput(
|
|
695
723
|
s,
|
|
696
724
|
e.frequency,
|
|
697
725
|
i,
|
|
698
726
|
a,
|
|
699
727
|
o,
|
|
700
|
-
(
|
|
728
|
+
(d) => u.math.setConfig(t, { frequency: d })
|
|
701
729
|
);
|
|
702
|
-
this.mathParamsContainer.appendChild(
|
|
703
|
-
const
|
|
730
|
+
this.mathParamsContainer.appendChild(l.row);
|
|
731
|
+
const h = this.createNumberInput(
|
|
704
732
|
"Amplitude",
|
|
705
733
|
e.amplitude,
|
|
706
734
|
0,
|
|
707
735
|
2,
|
|
708
736
|
0.1,
|
|
709
|
-
(
|
|
737
|
+
(d) => u.math.setConfig(t, { amplitude: d })
|
|
710
738
|
);
|
|
711
|
-
this.mathParamsContainer.appendChild(
|
|
712
|
-
const
|
|
739
|
+
this.mathParamsContainer.appendChild(h.row);
|
|
740
|
+
const p = this.createNumberInput(
|
|
713
741
|
"Offset",
|
|
714
742
|
e.offset,
|
|
715
743
|
0,
|
|
716
744
|
1,
|
|
717
745
|
0.1,
|
|
718
|
-
(
|
|
746
|
+
(d) => u.math.setConfig(t, { offset: d })
|
|
719
747
|
);
|
|
720
|
-
if (this.mathParamsContainer.appendChild(
|
|
721
|
-
const
|
|
748
|
+
if (this.mathParamsContainer.appendChild(p.row), ["sine", "sawtooth", "triangle", "square"].includes(t)) {
|
|
749
|
+
const d = this.createNumberInput(
|
|
722
750
|
"Phase",
|
|
723
751
|
e.phase,
|
|
724
752
|
0,
|
|
725
753
|
1,
|
|
726
754
|
0.01,
|
|
727
|
-
(
|
|
755
|
+
(b) => u.math.setConfig(t, { phase: b })
|
|
728
756
|
);
|
|
729
|
-
this.mathParamsContainer.appendChild(
|
|
757
|
+
this.mathParamsContainer.appendChild(d.row);
|
|
730
758
|
}
|
|
731
759
|
}
|
|
732
760
|
setSignalType(t) {
|
|
@@ -742,7 +770,7 @@ class B {
|
|
|
742
770
|
"square",
|
|
743
771
|
"random"
|
|
744
772
|
].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,
|
|
773
|
+
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, u.audio.ctx.state === "suspended" && u.audio.setInput("microphone")) : e || (this.currentMidiId = null), this.start(), this.signalSelect.value !== t && (this.signalSelect.value = t);
|
|
746
774
|
}
|
|
747
775
|
}
|
|
748
776
|
setMidiId(t) {
|
|
@@ -775,7 +803,7 @@ class B {
|
|
|
775
803
|
this.setSignalType("none"), this.setEase("linear"), this.setBehaviour("forward"), this.setMidiId(null);
|
|
776
804
|
}
|
|
777
805
|
}
|
|
778
|
-
class
|
|
806
|
+
class tt extends u {
|
|
779
807
|
constructor(t, e, s = {}) {
|
|
780
808
|
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
809
|
const i = r("details", {
|
|
@@ -794,38 +822,38 @@ class G extends d {
|
|
|
794
822
|
},
|
|
795
823
|
[String(this.value.toFixed(1))]
|
|
796
824
|
), this.input.addEventListener("input", () => {
|
|
797
|
-
const
|
|
798
|
-
isNaN(
|
|
799
|
-
}), this.input.addEventListener("click", (
|
|
800
|
-
|
|
825
|
+
const g = parseFloat(this.input.value);
|
|
826
|
+
isNaN(g) || (this.setValue(g), this.display.textContent = String(g.toFixed(1)));
|
|
827
|
+
}), this.input.addEventListener("click", (g) => {
|
|
828
|
+
g.stopPropagation();
|
|
801
829
|
});
|
|
802
830
|
const o = r("div", {
|
|
803
831
|
className: "cp-controller-summary-content"
|
|
804
832
|
});
|
|
805
833
|
o.appendChild(this.input), o.appendChild(this.display), a.appendChild(o), i.appendChild(a);
|
|
806
|
-
const
|
|
834
|
+
const l = r("div", { className: "cp-number-settings" }), h = this.createSetting(
|
|
807
835
|
"min",
|
|
808
836
|
s.min,
|
|
809
|
-
(
|
|
837
|
+
(g) => this.setMin(g)
|
|
810
838
|
);
|
|
811
|
-
this.minInput =
|
|
812
|
-
const
|
|
839
|
+
this.minInput = h.input, l.appendChild(h.row);
|
|
840
|
+
const p = this.createSetting(
|
|
813
841
|
"max",
|
|
814
842
|
s.max,
|
|
815
|
-
(
|
|
843
|
+
(g) => this.setMax(g)
|
|
816
844
|
);
|
|
817
|
-
this.maxInput =
|
|
818
|
-
const
|
|
845
|
+
this.maxInput = p.input, l.appendChild(p.row);
|
|
846
|
+
const d = this.createSetting(
|
|
819
847
|
"step",
|
|
820
848
|
s.step,
|
|
821
|
-
(
|
|
849
|
+
(g) => this.setStep(g)
|
|
822
850
|
);
|
|
823
|
-
this.stepInput =
|
|
824
|
-
const
|
|
825
|
-
|
|
826
|
-
container:
|
|
827
|
-
onChange: (
|
|
828
|
-
}), i.appendChild(
|
|
851
|
+
this.stepInput = d.input, l.appendChild(d.row);
|
|
852
|
+
const b = r("hr", { className: "cp-separator" });
|
|
853
|
+
l.appendChild(b), this.signalHandler = new H({
|
|
854
|
+
container: l,
|
|
855
|
+
onChange: (g, v) => this.applySignal(g, v)
|
|
856
|
+
}), i.appendChild(l), this.appendWidget(i);
|
|
829
857
|
}
|
|
830
858
|
// Setters
|
|
831
859
|
setMin(t) {
|
|
@@ -906,7 +934,7 @@ class G extends d {
|
|
|
906
934
|
), this.setStep(this.initialOptions.step), this.signalHandler?.reset();
|
|
907
935
|
}
|
|
908
936
|
}
|
|
909
|
-
class
|
|
937
|
+
class et extends u {
|
|
910
938
|
constructor(t, e, s) {
|
|
911
939
|
super(t, e, s), this.optionValues = [], this.select = r("select", { className: "cp-select" }), this.optionValues = s.options || [], this.optionValues.forEach((i, a) => {
|
|
912
940
|
const o = r("option", { value: String(a) }, [
|
|
@@ -931,7 +959,7 @@ class Z extends d {
|
|
|
931
959
|
t !== -1 && (this.select.value = String(t));
|
|
932
960
|
}
|
|
933
961
|
}
|
|
934
|
-
class
|
|
962
|
+
class st extends u {
|
|
935
963
|
constructor(t, e, s = {}) {
|
|
936
964
|
const i = { action: e };
|
|
937
965
|
super(i, "action", s);
|
|
@@ -946,7 +974,7 @@ class K extends d {
|
|
|
946
974
|
updateDisplay() {
|
|
947
975
|
}
|
|
948
976
|
}
|
|
949
|
-
class
|
|
977
|
+
class it extends u {
|
|
950
978
|
constructor(t, e, s = {}) {
|
|
951
979
|
super(t, e, s), this.input = r("input", {
|
|
952
980
|
type: "checkbox",
|
|
@@ -959,7 +987,7 @@ class Y extends d {
|
|
|
959
987
|
this.input.checked = this.value;
|
|
960
988
|
}
|
|
961
989
|
}
|
|
962
|
-
class
|
|
990
|
+
class nt extends u {
|
|
963
991
|
constructor(t, e, s) {
|
|
964
992
|
super(t, e, s), this.buttons = [], this.optionValues = [], this.container = r("div", { className: "cp-radios" }), this.optionValues = s.options || [], this.optionValues.forEach((i) => {
|
|
965
993
|
const a = r("button", { className: "cp-button cp-radio" }, [
|
|
@@ -977,7 +1005,7 @@ class Q extends d {
|
|
|
977
1005
|
});
|
|
978
1006
|
}
|
|
979
1007
|
}
|
|
980
|
-
class
|
|
1008
|
+
class at extends u {
|
|
981
1009
|
constructor(t, e, s = {}) {
|
|
982
1010
|
super(t, e, s), this.input = r("input", {
|
|
983
1011
|
type: "color",
|
|
@@ -992,7 +1020,7 @@ class X extends d {
|
|
|
992
1020
|
this.input.value = this.value;
|
|
993
1021
|
}
|
|
994
1022
|
}
|
|
995
|
-
function
|
|
1023
|
+
function $(n) {
|
|
996
1024
|
const t = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
|
997
1025
|
n = n.replace(t, (s, i, a, o) => i + i + a + a + o + o);
|
|
998
1026
|
const e = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(n);
|
|
@@ -1002,21 +1030,21 @@ function F(n) {
|
|
|
1002
1030
|
parseInt(e[3], 16)
|
|
1003
1031
|
] : [0, 0, 0];
|
|
1004
1032
|
}
|
|
1005
|
-
function
|
|
1033
|
+
function ot(n, t, e) {
|
|
1006
1034
|
return "#" + ((1 << 24) + (Math.round(n) << 16) + (Math.round(t) << 8) + Math.round(e)).toString(16).slice(1);
|
|
1007
1035
|
}
|
|
1008
|
-
function
|
|
1036
|
+
function T(n) {
|
|
1009
1037
|
const t = n / 255;
|
|
1010
1038
|
return t <= 0.04045 ? t / 12.92 : Math.pow((t + 0.055) / 1.055, 2.4);
|
|
1011
1039
|
}
|
|
1012
|
-
function
|
|
1040
|
+
function D(n) {
|
|
1013
1041
|
return n <= 31308e-7 ? n * 12.92 * 255 : (1.055 * Math.pow(n, 1 / 2.4) - 0.055) * 255;
|
|
1014
1042
|
}
|
|
1015
|
-
function
|
|
1016
|
-
const [s, i, a] =
|
|
1017
|
-
return
|
|
1043
|
+
function rt(n, t, e) {
|
|
1044
|
+
const [s, i, a] = $(n), [o, l, h] = $(t), p = T(s), d = T(i), b = T(a), g = T(o), v = T(l), E = T(h), f = p + e * (g - p), V = d + e * (v - d), x = b + e * (E - b), c = D(f), m = D(V), y = D(x);
|
|
1045
|
+
return ot(c, m, y);
|
|
1018
1046
|
}
|
|
1019
|
-
class
|
|
1047
|
+
class lt extends u {
|
|
1020
1048
|
constructor(t, e, s = {}) {
|
|
1021
1049
|
super(t, e, s), this.stops = [], this.pingPongDirection = 1, this.animationT = 0, this.manualPosition = 0, this.initialOptions = s, this.stops = s.stops || [
|
|
1022
1050
|
{ color: "#000000", position: 0 },
|
|
@@ -1037,25 +1065,25 @@ class st extends d {
|
|
|
1037
1065
|
{ className: "cp-value-display" },
|
|
1038
1066
|
[String(this.value)]
|
|
1039
1067
|
), o.appendChild(this.displayColor), o.appendChild(this.displayText), a.appendChild(o), i.appendChild(a);
|
|
1040
|
-
const
|
|
1068
|
+
const l = r("div", { className: "cp-number-settings" });
|
|
1041
1069
|
this.stopsContainer = r("div", {
|
|
1042
1070
|
className: "cp-stops-container"
|
|
1043
|
-
}), this.renderStops(),
|
|
1044
|
-
const
|
|
1071
|
+
}), this.renderStops(), l.appendChild(this.stopsContainer);
|
|
1072
|
+
const h = r(
|
|
1045
1073
|
"button",
|
|
1046
1074
|
{
|
|
1047
1075
|
className: "cp-button"
|
|
1048
1076
|
},
|
|
1049
1077
|
["+ Add Stop"]
|
|
1050
1078
|
);
|
|
1051
|
-
|
|
1079
|
+
h.addEventListener("click", () => {
|
|
1052
1080
|
this.stops.push({ color: "#ffffff", position: 0.5 }), this.sortStops(), this.renderStops(), this.updateOutput();
|
|
1053
|
-
}),
|
|
1054
|
-
const
|
|
1055
|
-
|
|
1056
|
-
container:
|
|
1057
|
-
onChange: (
|
|
1058
|
-
}), i.appendChild(
|
|
1081
|
+
}), l.appendChild(h);
|
|
1082
|
+
const p = r("hr", { className: "cp-separator" });
|
|
1083
|
+
l.appendChild(p), this.signalHandler = new H({
|
|
1084
|
+
container: l,
|
|
1085
|
+
onChange: (d, b) => this.applySignal(d, b)
|
|
1086
|
+
}), i.appendChild(l), this.appendWidget(i), this.updateOutput(0);
|
|
1059
1087
|
}
|
|
1060
1088
|
sortStops() {
|
|
1061
1089
|
this.stops.sort((t, e) => t.position - e.position);
|
|
@@ -1067,8 +1095,8 @@ class st extends d {
|
|
|
1067
1095
|
className: "cp-input-color",
|
|
1068
1096
|
value: t.color
|
|
1069
1097
|
});
|
|
1070
|
-
i.addEventListener("input", (
|
|
1071
|
-
t.color =
|
|
1098
|
+
i.addEventListener("input", (l) => {
|
|
1099
|
+
t.color = l.target.value, this.updateOutput();
|
|
1072
1100
|
});
|
|
1073
1101
|
const a = r("input", {
|
|
1074
1102
|
type: "number",
|
|
@@ -1078,11 +1106,11 @@ class st extends d {
|
|
|
1078
1106
|
step: "0.01",
|
|
1079
1107
|
value: String(t.position)
|
|
1080
1108
|
});
|
|
1081
|
-
a.addEventListener("change", (
|
|
1082
|
-
let
|
|
1083
|
-
isNaN(
|
|
1109
|
+
a.addEventListener("change", (l) => {
|
|
1110
|
+
let h = parseFloat(l.target.value);
|
|
1111
|
+
isNaN(h) && (h = 0), t.position = Math.max(0, Math.min(1, h)), this.sortStops(), this.renderStops(), this.updateOutput();
|
|
1084
1112
|
});
|
|
1085
|
-
const o =
|
|
1113
|
+
const o = j(() => {
|
|
1086
1114
|
this.stops.splice(e, 1), this.renderStops(), this.updateOutput();
|
|
1087
1115
|
});
|
|
1088
1116
|
s.appendChild(i), s.appendChild(a), s.appendChild(o), this.stopsContainer.appendChild(s);
|
|
@@ -1104,8 +1132,8 @@ class st extends d {
|
|
|
1104
1132
|
for (let s = 0; s < this.stops.length - 1; s++) {
|
|
1105
1133
|
const i = this.stops[s], a = this.stops[s + 1];
|
|
1106
1134
|
if (t >= i.position && t <= a.position) {
|
|
1107
|
-
const o = a.position - i.position,
|
|
1108
|
-
e =
|
|
1135
|
+
const o = a.position - i.position, l = o === 0 ? 0 : (t - i.position) / o;
|
|
1136
|
+
e = rt(i.color, a.color, l);
|
|
1109
1137
|
break;
|
|
1110
1138
|
}
|
|
1111
1139
|
}
|
|
@@ -1144,7 +1172,7 @@ class st extends d {
|
|
|
1144
1172
|
], this.sortStops(), this.renderStops(), this.signalHandler?.reset(), this.updateOutput(0);
|
|
1145
1173
|
}
|
|
1146
1174
|
}
|
|
1147
|
-
class
|
|
1175
|
+
class ct extends u {
|
|
1148
1176
|
constructor(t, e, s = {}) {
|
|
1149
1177
|
super(t, e, s), this.items = [], this.initialOptions = s, this.itemType = s.itemType || "string", this.items = this.parseValue(this.value);
|
|
1150
1178
|
const i = r("details", {
|
|
@@ -1153,15 +1181,15 @@ class it extends d {
|
|
|
1153
1181
|
className: "cp-controller-summary"
|
|
1154
1182
|
}), o = r("div", {
|
|
1155
1183
|
className: "cp-controller-summary-content"
|
|
1156
|
-
}),
|
|
1184
|
+
}), l = r("span", { className: "cp-value-display" }, [
|
|
1157
1185
|
`${this.items.length} items`
|
|
1158
1186
|
]);
|
|
1159
|
-
o.appendChild(
|
|
1160
|
-
const
|
|
1187
|
+
o.appendChild(l), a.appendChild(o), i.appendChild(a);
|
|
1188
|
+
const h = r("div", { className: "cp-number-settings" });
|
|
1161
1189
|
this.itemsContainer = r("div", {
|
|
1162
1190
|
className: "cp-stops-container"
|
|
1163
|
-
}), this.renderItems(),
|
|
1164
|
-
const
|
|
1191
|
+
}), this.renderItems(), h.appendChild(this.itemsContainer);
|
|
1192
|
+
const p = r(
|
|
1165
1193
|
"button",
|
|
1166
1194
|
{
|
|
1167
1195
|
className: "cp-button cp-input-small",
|
|
@@ -1169,9 +1197,9 @@ class it extends d {
|
|
|
1169
1197
|
},
|
|
1170
1198
|
["+ Add Item"]
|
|
1171
1199
|
);
|
|
1172
|
-
|
|
1200
|
+
p.addEventListener("click", () => {
|
|
1173
1201
|
this.addItem();
|
|
1174
|
-
}),
|
|
1202
|
+
}), h.appendChild(p), i.appendChild(h), this.appendWidget(i);
|
|
1175
1203
|
}
|
|
1176
1204
|
parseValue(t) {
|
|
1177
1205
|
return !t || t.trim() === "" ? [] : t.split(",").map((e) => e.trim());
|
|
@@ -1221,7 +1249,7 @@ class it extends d {
|
|
|
1221
1249
|
}), i.addEventListener("input", (o) => {
|
|
1222
1250
|
this.items[e] = o.target.value, this.updateValue();
|
|
1223
1251
|
});
|
|
1224
|
-
const a =
|
|
1252
|
+
const a = j(() => {
|
|
1225
1253
|
this.items.splice(e, 1), this.renderItems(), this.updateValue();
|
|
1226
1254
|
});
|
|
1227
1255
|
s.appendChild(i), s.appendChild(a), this.itemsContainer.appendChild(s);
|
|
@@ -1240,7 +1268,7 @@ class it extends d {
|
|
|
1240
1268
|
this.items = this.parseValue(t), this.renderItems(), this.updateValue();
|
|
1241
1269
|
}
|
|
1242
1270
|
}
|
|
1243
|
-
class
|
|
1271
|
+
class ht {
|
|
1244
1272
|
constructor() {
|
|
1245
1273
|
this.frames = 0, this.pollingInterval = 1e3, this.prevTime = performance.now(), this.render = () => {
|
|
1246
1274
|
this.frames++;
|
|
@@ -1258,44 +1286,44 @@ class nt {
|
|
|
1258
1286
|
cancelAnimationFrame(this.rafId);
|
|
1259
1287
|
}
|
|
1260
1288
|
}
|
|
1261
|
-
class
|
|
1289
|
+
class U {
|
|
1262
1290
|
constructor() {
|
|
1263
1291
|
this.controllers = [], this.folders = [];
|
|
1264
1292
|
}
|
|
1265
1293
|
addNumber(t, e, s = {}) {
|
|
1266
|
-
const i = new
|
|
1294
|
+
const i = new tt(t, e, s);
|
|
1267
1295
|
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
1268
1296
|
}
|
|
1269
1297
|
addSelect(t, e, s = {}) {
|
|
1270
|
-
const i = new
|
|
1298
|
+
const i = new et(t, e, s);
|
|
1271
1299
|
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
1272
1300
|
}
|
|
1273
1301
|
addBoolean(t, e, s = {}) {
|
|
1274
|
-
const i = new
|
|
1302
|
+
const i = new it(t, e, s);
|
|
1275
1303
|
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
1276
1304
|
}
|
|
1277
1305
|
addButton(t, e, s = {}) {
|
|
1278
|
-
const i = new
|
|
1306
|
+
const i = new st(t, e, s);
|
|
1279
1307
|
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
1280
1308
|
}
|
|
1281
1309
|
addRadio(t, e, s = {}) {
|
|
1282
|
-
const i = new
|
|
1310
|
+
const i = new nt(t, e, s);
|
|
1283
1311
|
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
1284
1312
|
}
|
|
1285
1313
|
addColor(t, e, s = {}) {
|
|
1286
|
-
const i = new
|
|
1314
|
+
const i = new at(t, e, s);
|
|
1287
1315
|
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
1288
1316
|
}
|
|
1289
1317
|
addGradient(t, e, s = {}) {
|
|
1290
|
-
const i = new
|
|
1318
|
+
const i = new lt(t, e, s);
|
|
1291
1319
|
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
1292
1320
|
}
|
|
1293
1321
|
addArray(t, e, s = {}) {
|
|
1294
|
-
const i = new
|
|
1322
|
+
const i = new ct(t, e, s);
|
|
1295
1323
|
return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
|
|
1296
1324
|
}
|
|
1297
1325
|
addFolder(t) {
|
|
1298
|
-
const e = new
|
|
1326
|
+
const e = new pt(t);
|
|
1299
1327
|
return this.contentElement.appendChild(e.domElement), this.folders.push(e), e;
|
|
1300
1328
|
}
|
|
1301
1329
|
save() {
|
|
@@ -1333,7 +1361,7 @@ class q {
|
|
|
1333
1361
|
t.reset();
|
|
1334
1362
|
}
|
|
1335
1363
|
}
|
|
1336
|
-
class
|
|
1364
|
+
class pt extends U {
|
|
1337
1365
|
constructor(t) {
|
|
1338
1366
|
super(), this.title = t, this.domElement = r("details", {
|
|
1339
1367
|
className: "cp-folder",
|
|
@@ -1351,9 +1379,9 @@ class at extends q {
|
|
|
1351
1379
|
);
|
|
1352
1380
|
}
|
|
1353
1381
|
}
|
|
1354
|
-
class
|
|
1382
|
+
class dt extends U {
|
|
1355
1383
|
constructor(t, e = {}) {
|
|
1356
|
-
super(),
|
|
1384
|
+
super(), _(), this.domElement = r("details", {
|
|
1357
1385
|
className: "cp-root",
|
|
1358
1386
|
open: !0
|
|
1359
1387
|
}), this.summaryElement = r("summary", {
|
|
@@ -1362,142 +1390,157 @@ class ot extends q {
|
|
|
1362
1390
|
const s = r("span", {}, [
|
|
1363
1391
|
e.title || "ControlPanel"
|
|
1364
1392
|
]);
|
|
1365
|
-
this.summaryElement.appendChild(s), this.stats = new
|
|
1366
|
-
|
|
1393
|
+
this.summaryElement.appendChild(s), this.stats = new ht(), this.summaryElement.appendChild(this.stats.domElement);
|
|
1394
|
+
let i = !1, a = 0, o = 0, l = 0, h = 0;
|
|
1395
|
+
this.summaryElement.addEventListener("mousedown", (c) => {
|
|
1396
|
+
if (c.target !== this.summaryElement && c.target !== s) return;
|
|
1397
|
+
i = !0, a = c.clientX, o = c.clientY;
|
|
1398
|
+
const m = this.domElement.getBoundingClientRect();
|
|
1399
|
+
l = m.left, h = m.top, c.preventDefault();
|
|
1400
|
+
}), document.addEventListener("mousemove", (c) => {
|
|
1401
|
+
if (!i) return;
|
|
1402
|
+
const m = c.clientX - a, y = c.clientY - o, S = l + m, k = h + y;
|
|
1403
|
+
this.domElement.style.left = `${S}px`, this.domElement.style.top = `${k}px`, this.domElement.style.right = "auto", this.domElement.style.bottom = "auto";
|
|
1404
|
+
}), document.addEventListener("mouseup", () => {
|
|
1405
|
+
i && (i = !1, this.savePositionAndSize());
|
|
1406
|
+
}), new ResizeObserver(() => {
|
|
1407
|
+
i || this.savePositionAndSize();
|
|
1408
|
+
}).observe(this.domElement), this.restorePositionAndSize(), this.contentElement = r("div", { className: "cp-content" }), this.domElement.appendChild(this.contentElement);
|
|
1409
|
+
const d = this.addFolder("_Signals"), b = {
|
|
1367
1410
|
audioInput: null,
|
|
1368
1411
|
fftSize: 2048
|
|
1369
1412
|
};
|
|
1370
|
-
|
|
1413
|
+
d.addRadio(b, "audioInput", {
|
|
1371
1414
|
label: "Audio Signal",
|
|
1372
1415
|
options: ["microphone", "browser"]
|
|
1373
|
-
}).onChange((
|
|
1374
|
-
|
|
1375
|
-
}),
|
|
1416
|
+
}).onChange((c) => {
|
|
1417
|
+
M.setInput(c);
|
|
1418
|
+
}), d.addSelect(b, "fftSize", {
|
|
1376
1419
|
label: "FFT Size",
|
|
1377
1420
|
options: [256, 512, 1024, 2048]
|
|
1378
|
-
}).onChange((
|
|
1379
|
-
|
|
1380
|
-
}),
|
|
1421
|
+
}).onChange((c) => {
|
|
1422
|
+
M.setFFTSize(c);
|
|
1423
|
+
}), d.addNumber(M, "smoothingTimeConstant", {
|
|
1381
1424
|
min: 0,
|
|
1382
1425
|
max: 0.99,
|
|
1383
1426
|
step: 0.01,
|
|
1384
1427
|
label: "Smoothing"
|
|
1385
|
-
}).onChange((
|
|
1386
|
-
|
|
1387
|
-
}),
|
|
1428
|
+
}).onChange((c) => {
|
|
1429
|
+
M.analyser.smoothingTimeConstant = c;
|
|
1430
|
+
}), d.addNumber(M, "spectrumBoost", {
|
|
1388
1431
|
min: 1,
|
|
1389
1432
|
max: 5,
|
|
1390
1433
|
step: 0.1,
|
|
1391
1434
|
label: "Compression"
|
|
1392
1435
|
}), t ? t.appendChild(this.domElement) : document.body.appendChild(this.domElement);
|
|
1393
|
-
const
|
|
1394
|
-
this.presetStoragePrefix = `cp-presets-${
|
|
1395
|
-
const
|
|
1396
|
-
const
|
|
1397
|
-
if (typeof localStorage > "u") return
|
|
1398
|
-
for (let
|
|
1399
|
-
const
|
|
1400
|
-
if (
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1436
|
+
const g = e.title || "ControlPanel";
|
|
1437
|
+
this.presetStoragePrefix = `cp-presets-${g}-`;
|
|
1438
|
+
const v = this.addFolder("_User Presets"), E = () => {
|
|
1439
|
+
const c = ["Default"];
|
|
1440
|
+
if (typeof localStorage > "u") return c;
|
|
1441
|
+
for (let m = 0; m < localStorage.length; m++) {
|
|
1442
|
+
const y = localStorage.key(m);
|
|
1443
|
+
if (y && y.startsWith(this.presetStoragePrefix)) {
|
|
1444
|
+
const S = y.substring(this.presetStoragePrefix.length);
|
|
1445
|
+
S !== "Default" && !c.includes(S) && c.push(S);
|
|
1403
1446
|
}
|
|
1404
1447
|
}
|
|
1405
|
-
return
|
|
1406
|
-
},
|
|
1448
|
+
return c.sort();
|
|
1449
|
+
}, f = {
|
|
1407
1450
|
selected: "Default",
|
|
1408
1451
|
save: () => {
|
|
1409
|
-
const
|
|
1410
|
-
if (
|
|
1411
|
-
if (
|
|
1452
|
+
const c = prompt("Preset Name:", f.selected);
|
|
1453
|
+
if (c) {
|
|
1454
|
+
if (c === "Default") {
|
|
1412
1455
|
alert("Cannot overwrite Default preset");
|
|
1413
1456
|
return;
|
|
1414
1457
|
}
|
|
1415
|
-
const
|
|
1416
|
-
this.saveToLocalStorage(
|
|
1417
|
-
const
|
|
1418
|
-
|
|
1458
|
+
const m = this.presetStoragePrefix + c;
|
|
1459
|
+
this.saveToLocalStorage(m);
|
|
1460
|
+
const y = E();
|
|
1461
|
+
x.setOptions(y), f.selected = c, x.setValue(c);
|
|
1419
1462
|
}
|
|
1420
1463
|
},
|
|
1421
1464
|
load: () => {
|
|
1422
|
-
const
|
|
1423
|
-
this.loadFromLocalStorage(
|
|
1465
|
+
const c = f.selected, m = this.presetStoragePrefix + c;
|
|
1466
|
+
this.loadFromLocalStorage(m), f.selected = c, x.setValue(c);
|
|
1424
1467
|
},
|
|
1425
1468
|
delete: () => {
|
|
1426
|
-
if (
|
|
1469
|
+
if (f.selected === "Default") {
|
|
1427
1470
|
alert("Cannot delete Default preset");
|
|
1428
1471
|
return;
|
|
1429
1472
|
}
|
|
1430
|
-
if (confirm(`Delete preset "${
|
|
1431
|
-
const
|
|
1432
|
-
localStorage.removeItem(
|
|
1433
|
-
const
|
|
1434
|
-
|
|
1473
|
+
if (confirm(`Delete preset "${f.selected}"?`)) {
|
|
1474
|
+
const c = this.presetStoragePrefix + f.selected;
|
|
1475
|
+
localStorage.removeItem(c);
|
|
1476
|
+
const m = E();
|
|
1477
|
+
x.setOptions(m), f.selected = "Default", x.setValue("Default"), this.reset();
|
|
1435
1478
|
}
|
|
1436
1479
|
},
|
|
1437
1480
|
export: () => {
|
|
1438
|
-
const
|
|
1439
|
-
const
|
|
1481
|
+
const c = this.save(), m = (O) => {
|
|
1482
|
+
const L = {
|
|
1440
1483
|
controllers: {},
|
|
1441
1484
|
folders: {}
|
|
1442
1485
|
};
|
|
1443
|
-
for (const [
|
|
1444
|
-
|
|
1445
|
-
for (const [
|
|
1446
|
-
|
|
1486
|
+
for (const [A, F] of Object.entries(O.controllers))
|
|
1487
|
+
A.startsWith("_") || (L.controllers[A] = F);
|
|
1488
|
+
for (const [A, F] of Object.entries(
|
|
1489
|
+
O.folders
|
|
1447
1490
|
))
|
|
1448
|
-
|
|
1449
|
-
return
|
|
1450
|
-
},
|
|
1451
|
-
_presetName:
|
|
1491
|
+
A.startsWith("_") || (L.folders[A] = m(F));
|
|
1492
|
+
return L;
|
|
1493
|
+
}, y = m(c), S = {
|
|
1494
|
+
_presetName: f.selected || "CustomPreset",
|
|
1452
1495
|
_exportDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1453
1496
|
_instructions: "To add as factory preset: Copy 'controllers' and 'folders' fields into the presets.json file",
|
|
1454
|
-
...
|
|
1455
|
-
},
|
|
1456
|
-
|
|
1457
|
-
const
|
|
1458
|
-
|
|
1497
|
+
...y
|
|
1498
|
+
}, k = JSON.stringify(S, null, 2), C = new Blob([k], { type: "application/json" }), I = URL.createObjectURL(C), w = document.createElement("a");
|
|
1499
|
+
w.href = I;
|
|
1500
|
+
const N = (/* @__PURE__ */ new Date()).toISOString().split("T")[0], z = f.selected.replace(/[^a-z0-9]/gi, "-").toLowerCase();
|
|
1501
|
+
w.download = `${g.toLowerCase()}-preset-${z}-${N}.json`, document.body.appendChild(w), w.click(), document.body.removeChild(w), URL.revokeObjectURL(I);
|
|
1459
1502
|
},
|
|
1460
1503
|
import: () => {
|
|
1461
|
-
const
|
|
1462
|
-
|
|
1463
|
-
const
|
|
1464
|
-
if (!
|
|
1465
|
-
const
|
|
1466
|
-
|
|
1504
|
+
const c = document.createElement("input");
|
|
1505
|
+
c.type = "file", c.accept = ".json", c.onchange = (m) => {
|
|
1506
|
+
const y = m.target.files?.[0];
|
|
1507
|
+
if (!y) return;
|
|
1508
|
+
const S = new FileReader();
|
|
1509
|
+
S.onload = (k) => {
|
|
1467
1510
|
try {
|
|
1468
|
-
const
|
|
1469
|
-
controllers:
|
|
1470
|
-
folders:
|
|
1511
|
+
const C = k.target?.result, I = JSON.parse(C), w = {
|
|
1512
|
+
controllers: I.controllers || {},
|
|
1513
|
+
folders: I.folders || {}
|
|
1471
1514
|
};
|
|
1472
|
-
if (!
|
|
1515
|
+
if (!w.controllers || !w.folders) {
|
|
1473
1516
|
alert(
|
|
1474
1517
|
"Invalid preset file: missing 'controllers' or 'folders'"
|
|
1475
1518
|
);
|
|
1476
1519
|
return;
|
|
1477
1520
|
}
|
|
1478
|
-
this.load(
|
|
1479
|
-
const
|
|
1521
|
+
this.load(w);
|
|
1522
|
+
const N = I._presetName || "ImportedPreset";
|
|
1480
1523
|
if (confirm(
|
|
1481
|
-
`Preset loaded! Save as "${
|
|
1524
|
+
`Preset loaded! Save as "${N}" to User Presets?`
|
|
1482
1525
|
)) {
|
|
1483
|
-
const
|
|
1484
|
-
this.saveToLocalStorage(
|
|
1485
|
-
const
|
|
1486
|
-
|
|
1526
|
+
const O = this.presetStoragePrefix + N;
|
|
1527
|
+
this.saveToLocalStorage(O);
|
|
1528
|
+
const L = E();
|
|
1529
|
+
x.setOptions(L), f.selected = N, x.setValue(N);
|
|
1487
1530
|
}
|
|
1488
|
-
} catch (
|
|
1531
|
+
} catch (C) {
|
|
1489
1532
|
alert(
|
|
1490
|
-
`Failed to import preset: ${
|
|
1491
|
-
), console.error("Import error:",
|
|
1533
|
+
`Failed to import preset: ${C instanceof Error ? C.message : "Invalid JSON"}`
|
|
1534
|
+
), console.error("Import error:", C);
|
|
1492
1535
|
}
|
|
1493
|
-
},
|
|
1494
|
-
},
|
|
1536
|
+
}, S.readAsText(y);
|
|
1537
|
+
}, c.click();
|
|
1495
1538
|
}
|
|
1496
|
-
},
|
|
1539
|
+
}, V = E(), x = v.addSelect(f, "selected", {
|
|
1497
1540
|
label: "Preset",
|
|
1498
|
-
options:
|
|
1541
|
+
options: V
|
|
1499
1542
|
});
|
|
1500
|
-
|
|
1543
|
+
v.addButton("Load", () => f.load()), v.addButton("Save / New", () => f.save()), v.addButton("Delete", () => f.delete()), v.addButton("Export JSON", () => f.export()), v.addButton("Import JSON", () => f.import());
|
|
1501
1544
|
}
|
|
1502
1545
|
saveToLocalStorage(t) {
|
|
1503
1546
|
const e = this.save();
|
|
@@ -1522,27 +1565,52 @@ class ot extends q {
|
|
|
1522
1565
|
const t = this.presetStoragePrefix + "Default";
|
|
1523
1566
|
this.save(), this.saveToLocalStorage(t);
|
|
1524
1567
|
}
|
|
1568
|
+
savePositionAndSize() {
|
|
1569
|
+
const t = this.domElement.getBoundingClientRect(), e = `cp-position-${this.presetStoragePrefix}`, s = {
|
|
1570
|
+
left: t.left,
|
|
1571
|
+
top: t.top,
|
|
1572
|
+
width: this.domElement.offsetWidth,
|
|
1573
|
+
height: this.domElement.offsetHeight
|
|
1574
|
+
};
|
|
1575
|
+
try {
|
|
1576
|
+
sessionStorage.setItem(e, JSON.stringify(s));
|
|
1577
|
+
} catch (i) {
|
|
1578
|
+
console.warn("Failed to save panel position/size", i);
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
restorePositionAndSize() {
|
|
1582
|
+
const t = `cp-position-${this.presetStoragePrefix}`;
|
|
1583
|
+
try {
|
|
1584
|
+
const e = sessionStorage.getItem(t);
|
|
1585
|
+
if (e) {
|
|
1586
|
+
const s = JSON.parse(e);
|
|
1587
|
+
this.domElement.style.left = `${s.left}px`, this.domElement.style.top = `${s.top}px`, this.domElement.style.right = "auto", this.domElement.style.bottom = "auto", this.domElement.style.width = `${s.width}px`, this.domElement.style.height = `${s.height}px`;
|
|
1588
|
+
}
|
|
1589
|
+
} catch (e) {
|
|
1590
|
+
console.warn("Failed to restore panel position/size", e);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1525
1593
|
destroy() {
|
|
1526
1594
|
this.stats.destroy(), this.domElement.remove(), this.controllers = [], this.folders = [];
|
|
1527
1595
|
}
|
|
1528
1596
|
}
|
|
1529
1597
|
export {
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1598
|
+
ct as ArrayController,
|
|
1599
|
+
X as AudioSignals,
|
|
1600
|
+
it as BooleanController,
|
|
1601
|
+
st as ButtonController,
|
|
1602
|
+
at as ColorController,
|
|
1603
|
+
dt as ControlPanel,
|
|
1604
|
+
U as ControlPanelContainer,
|
|
1605
|
+
u as Controller,
|
|
1606
|
+
pt as Folder,
|
|
1607
|
+
lt as GradientController,
|
|
1608
|
+
K as MathSignals,
|
|
1609
|
+
G as MidiSignals,
|
|
1610
|
+
tt as NumberController,
|
|
1611
|
+
nt as RadioController,
|
|
1612
|
+
et as SelectController,
|
|
1613
|
+
M as audioSignals,
|
|
1614
|
+
Q as mathSignals,
|
|
1615
|
+
Z as midiSignals
|
|
1548
1616
|
};
|