Make the main program a server and add knobs along with some mappings
This commit is contained in:
148
view/assets/scripts/knobs.js
Normal file
148
view/assets/scripts/knobs.js
Normal file
@ -0,0 +1,148 @@
|
||||
class KnobElement extends HTMLElement {
|
||||
static observedAttributes = ["min", "max", "value", "step"];
|
||||
|
||||
_min = -1;
|
||||
rawValue = 0;
|
||||
_value = 0;
|
||||
step = 1;
|
||||
_max = 1;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
connectedCallback() {
|
||||
// if ("min" in this.attributes) {
|
||||
// this._min = parseFloat(this.attributes["min"].value);
|
||||
// }
|
||||
// if ("max" in this.attributes) {
|
||||
// this._max = parseFloat(this.attributes["max"].value);
|
||||
// }
|
||||
if ("value" in this.attributes) {
|
||||
this.value = parseFloat(this.attributes["value"].value);
|
||||
}
|
||||
// if ("step" in this.attributes) {
|
||||
// this.step = parseFloat(this.attributes["step"].value);
|
||||
// }
|
||||
|
||||
var shadow = this.attachShadow({
|
||||
"mode": "open"
|
||||
});
|
||||
|
||||
var style = document.createElement("style");
|
||||
style.textContent = `
|
||||
#wrapper {
|
||||
background-color: rgba(24, 24, 24, 1.0);
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
#cursor {
|
||||
position: relative;
|
||||
background-color: rgba(232, 232, 232, 1.0);
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
left: calc(50% - 2px);
|
||||
}
|
||||
`;
|
||||
|
||||
var wrapper = document.createElement("div");
|
||||
wrapper.id = "wrapper";
|
||||
|
||||
wrapper.onmousedown = (function (event) {
|
||||
window.onmousemove = (function (event) {
|
||||
this.rawValue += event.movementX / 2;
|
||||
if (this.rawValue < -128) {
|
||||
this.rawValue = -128;
|
||||
}
|
||||
if (this.rawValue > 127) {
|
||||
this.rawValue = 127;
|
||||
}
|
||||
var range = this._max - this._min;
|
||||
var theoreticalValue = (((this.rawValue + Math.abs(-128)) * range) / 255) + this._min;
|
||||
|
||||
var invertedStep = 1 / this.step;
|
||||
this._value = Math.round(theoreticalValue * invertedStep) / invertedStep;
|
||||
|
||||
|
||||
this.wrapper.style.rotate = String((this.rawValue * 135) / 128) + "deg";
|
||||
|
||||
var inputEvent = new InputEvent("input");
|
||||
this.dispatchEvent(inputEvent);
|
||||
}).bind(this);
|
||||
|
||||
window.onmouseup = function (event) {
|
||||
window.onmousemove = null;
|
||||
window.onmouseup = null;
|
||||
};
|
||||
}).bind(this);
|
||||
|
||||
var cursor = document.createElement("div");
|
||||
cursor.id = "cursor";
|
||||
|
||||
wrapper.appendChild(cursor);
|
||||
|
||||
shadow.appendChild(style);
|
||||
shadow.appendChild(wrapper);
|
||||
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
this[name] = parseFloat(newValue);
|
||||
}
|
||||
get min() {
|
||||
return this._min;
|
||||
}
|
||||
set min(value) {
|
||||
if (isNaN(value)) return;
|
||||
|
||||
this._min = value;
|
||||
|
||||
if (this._value < this._min) {
|
||||
this._value = this._min;
|
||||
}
|
||||
|
||||
this.rawValue = (((this._value + Math.abs(this._min)) * 255) / (this._max - this._min)) + -128;
|
||||
|
||||
if ("wrapper" in this)
|
||||
this.wrapper.style.rotate = String((this.rawValue * 135) / 128) + "deg";
|
||||
}
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
set value(value) {
|
||||
if (isNaN(value)) return;
|
||||
|
||||
if (value < this._min) {
|
||||
this._value = this._min;
|
||||
} else if (value > this._max) {
|
||||
this._value = this._max;
|
||||
} else {
|
||||
this._value = value;
|
||||
}
|
||||
|
||||
this.rawValue = (((this._value + Math.abs(this._min)) * 255) / (this._max - this._min)) + -128;
|
||||
|
||||
if ("wrapper" in this)
|
||||
this.wrapper.style.rotate = String((this.rawValue * 135) / 128) + "deg";
|
||||
}
|
||||
get max() {
|
||||
return this._max;
|
||||
}
|
||||
set max(value) {
|
||||
if (isNaN(value)) return;
|
||||
|
||||
this._max = value;
|
||||
|
||||
if (this._value > this._max) {
|
||||
this._value = this._max;
|
||||
}
|
||||
|
||||
this.rawValue = (((this._value + Math.abs(this._min)) * 255) / (this._max - this._min)) + -128;
|
||||
|
||||
if ("wrapper" in this)
|
||||
this.wrapper.style.rotate = String((this.rawValue * 135) / 128) + "deg";
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("knob-input", KnobElement);
|
@ -69,9 +69,15 @@ if (!("controller" in window)) {
|
||||
"play_pause": function (deckIndex) {
|
||||
sendControl("deck" + String(deckIndex) + ".play_pause");
|
||||
},
|
||||
"sync": function (deckIndex) {
|
||||
sendControl("deck" + String(deckIndex) + ".sync");
|
||||
},
|
||||
"volume": function (deckIndex, value) {
|
||||
sendControl("deck" + String(deckIndex) + ".volume", value);
|
||||
},
|
||||
"eq": function (deckIndex, freq, value) {
|
||||
sendControl("deck" + String(deckIndex) + ".eq_" + freq, value);
|
||||
},
|
||||
"speed": function (deckIndex, value) {
|
||||
sendControl("deck" + String(deckIndex) + ".speed", value);
|
||||
},
|
||||
|
@ -4,6 +4,10 @@
|
||||
background-color: rgba(8, 12, 16, 1.0);
|
||||
}
|
||||
|
||||
* {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
:root, body, main, #sections {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@ -18,12 +22,12 @@ button {
|
||||
min-height: 64px;
|
||||
}
|
||||
|
||||
#sections, .deck, #mixer, #volume, #volume-meters, .volume-meter, .deck-pads {
|
||||
#sections, .deck, #mixer, #eq-knobs, #volume, #volume-meters, .volume-meter, .deck-pads {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#sections, #volume, #volume-meters, .deck-pads {
|
||||
#sections, #eq-knobs, #volume, #volume-meters, .deck-pads {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user