diff --git a/web_realart/public/control/control.css b/web_realart/public/control/control.css new file mode 100644 index 0000000..eff1250 --- /dev/null +++ b/web_realart/public/control/control.css @@ -0,0 +1,12 @@ +* { box-sizing: border-box; } body { margin: 0; background: #111; color: #eee; + font: 16px/1.3 -apple-system, system-ui, sans-serif; padding: 12px; } +header { display: flex; align-items: center; gap: 10px; } +h1 { font-size: 18px; margin: 4px 0; } h2 { font-size: 14px; color: #9af; margin: 16px 0 8px; text-transform: uppercase; letter-spacing: .06em; } +#status { width: 12px; height: 12px; border-radius: 50%; display: inline-block; } +#status.on { background: #4c8; } #status.off { background: #c44; } +.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; } +button { background: #222; color: #eee; border: 1px solid #333; border-radius: 10px; + padding: 18px 10px; font-size: 16px; cursor: pointer; } +button:active { background: #2a2a2a; } button.armed { background: #2b6; color: #061; border-color: #4d9; font-weight: 700; } +button.wide { width: 100%; margin: 8px 0; background: #422; border-color: #633; } +label { display: block; margin: 10px 0; } input[type=range] { width: 100%; height: 36px; } diff --git a/web_realart/public/control/control.js b/web_realart/public/control/control.js new file mode 100644 index 0000000..39df2a3 --- /dev/null +++ b/web_realart/public/control/control.js @@ -0,0 +1,31 @@ +const ws = new WebSocket(`ws://${location.host}/ws`); +const dot = () => document.getElementById("status"); +ws.addEventListener("open", () => dot().className = "on"); +ws.addEventListener("close", () => dot().className = "off"); +function send(address, ...args) { + if (ws.readyState === 1) ws.send(JSON.stringify({ address, args })); +} +const armed = new Set(); +function togglePad(el, name) { + const on = !armed.has(name); + on ? armed.add(name) : armed.delete(name); + el.classList.toggle("armed", on); + send("/launch", name, on ? 1 : 0); +} +document.addEventListener("DOMContentLoaded", () => { + document.querySelectorAll("[data-pad]").forEach((el) => + el.addEventListener("click", () => togglePad(el, el.dataset.pad))); + document.querySelectorAll("[data-osc]").forEach((el) => + el.addEventListener("click", () => { + const a = el.dataset.arg; + send(el.dataset.osc, ...(a === undefined ? [] : [isNaN(+a) ? a : +a])); + })); + const tempo = document.getElementById("tempo"); + tempo && tempo.addEventListener("input", () => send("/launch/tempo", +tempo.value)); + const filt = document.getElementById("filter"); + filt && filt.addEventListener("input", () => send("/control/fx/filter", +filt.value)); + document.getElementById("clear").addEventListener("click", () => { + armed.clear(); document.querySelectorAll("[data-pad]").forEach((e) => e.classList.remove("armed")); + send("/launch/clear"); + }); +}); diff --git a/web_realart/public/control/index.html b/web_realart/public/control/index.html new file mode 100644 index 0000000..9437bc0 --- /dev/null +++ b/web_realart/public/control/index.html @@ -0,0 +1,51 @@ + + +AV-Live — Control + +

AV-Live Control

+

Patterns

+
+ + + + + +
+ + +
+

Concert

+
+ + + +
+
+

Harmonie

+
+ + + + + + + + + + + + +
+
+

FX

+ +
+ + + + + + +
+
+