feat(control): fist sensitivity + indicators
CI build oscope-of / build-check (push) Has been cancelled
CI build oscope-of / build-check (push) Has been cancelled
Add matFistThresh state (default 0.15) with localStorage persistence. Wire a "Sensibilite poing" slider in Reglages, synced via fisthresh. Add two fist indicator rows in #morceau-fists driven by fistprogress.
This commit is contained in:
@@ -251,3 +251,6 @@ button.queued { animation: queued-blink 600ms ease-in-out infinite alternate; }
|
||||
.morceau-global { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px; }
|
||||
.morceau-global .morceau-bpm { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: #ccc; }
|
||||
.morceau-global .morceau-bpm output { min-width: 2.5em; text-align: right; color: #8c8; }
|
||||
.morceau-fists { display: flex; flex-direction: column; gap: 4px; }
|
||||
.morceau-fist { position: relative; font-size: 12px; color: #ccc; padding: 2px 4px;
|
||||
background: #1c1c1c; border-radius: 4px; }
|
||||
|
||||
@@ -186,6 +186,8 @@
|
||||
<div id="morceau-slots" class="morceau-slots"></div>
|
||||
<div class="morceau-title">Réglages</div>
|
||||
<div id="morceau-settings" class="morceau-settings"></div>
|
||||
<div class="morceau-title">Poings</div>
|
||||
<div id="morceau-fists" class="morceau-fists"></div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -88,6 +88,8 @@ export function resetGlobalSettings() { matGlobalSettings = { transientBars: 1,
|
||||
|
||||
export let matPinchHoldMs = 300;
|
||||
export function setPinchHoldMs(v) { matPinchHoldMs = v; }
|
||||
export let matFistThresh = 0.15;
|
||||
export function setFistThresh(v) { matFistThresh = v; }
|
||||
// Decode /matrix/globalsettings args: [transientBars, keepN, keep0..]
|
||||
export function parseGlobalSettings(args) {
|
||||
const transientBars = Math.round(Number(args[0]));
|
||||
@@ -190,7 +192,8 @@ export function saveMatState() {
|
||||
try { localStorage.setItem(MATRIX_STORAGE_KEY,
|
||||
JSON.stringify({ grid: matGrid, inst: matInst, cdef: matColorDefs,
|
||||
vmod: matVoiceMods, vpose: matVoicePoses,
|
||||
gact: matGlobalActions, gset: matGlobalSettings, phms: matPinchHoldMs })); } catch (_e) {}
|
||||
gact: matGlobalActions, gset: matGlobalSettings, phms: matPinchHoldMs,
|
||||
fth: matFistThresh })); } catch (_e) {}
|
||||
}
|
||||
|
||||
export function loadMatState() {
|
||||
@@ -220,6 +223,7 @@ export function loadMatState() {
|
||||
if (raw.gset && typeof raw.gset === "object" && Array.isArray(raw.gset.breakdownKeep))
|
||||
matGlobalSettings = raw.gset;
|
||||
if (Number.isFinite(raw.phms)) matPinchHoldMs = raw.phms;
|
||||
if (Number.isFinite(raw.fth)) matFistThresh = raw.fth;
|
||||
return; }
|
||||
if (Array.isArray(raw) && raw.length === MATRIX_VOICES.length) { matGrid = raw; return; } // legacy: bare grid
|
||||
} catch (_e) {}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
GLOBAL_ACTION_CHOICES, GLOBAL_SLOTS, matGlobalActions, setGlobalAction, saveMatState,
|
||||
matGlobalSettings, setGlobalSetting, parseGlobalSettings,
|
||||
matPinchHoldMs, setPinchHoldMs,
|
||||
matFistThresh, setFistThresh,
|
||||
} from "./matrix-state.js";
|
||||
import { MATRIX_VOICES } from "./matrix-state.js";
|
||||
|
||||
@@ -90,6 +91,23 @@ export function init() {
|
||||
});
|
||||
onOpen(() => send("/matrix/pinchhold/get"));
|
||||
send("/matrix/pinchhold/get");
|
||||
// --- Sensibilite poing slider (in Reglages) ---
|
||||
const fRow = document.createElement("label");
|
||||
fRow.className = "morceau-set-row";
|
||||
const fSpan = document.createElement("span"); fSpan.textContent = "Sensibilité poing";
|
||||
const fInp = document.createElement("input");
|
||||
fInp.type = "range"; fInp.min = 0.05; fInp.max = 0.5; fInp.step = 0.01; fInp.value = matFistThresh;
|
||||
const fOut = document.createElement("output"); fOut.textContent = matFistThresh;
|
||||
fInp.addEventListener("input", () => { fOut.textContent = fInp.value; });
|
||||
fInp.addEventListener("change", () => { setFistThresh(+fInp.value); send("/matrix/fisthresh", +fInp.value); saveMatState(); });
|
||||
fRow.append(fSpan, fInp, fOut);
|
||||
sHost.appendChild(fRow);
|
||||
on("/matrix/fisthresh", (args) => {
|
||||
const v = Number(args[0]);
|
||||
if (Number.isFinite(v)) { fInp.value = v; fOut.textContent = v; setFistThresh(v); saveMatState(); }
|
||||
});
|
||||
onOpen(() => send("/matrix/fisthresh/get"));
|
||||
send("/matrix/fisthresh/get");
|
||||
const keepWrap = document.createElement("div");
|
||||
keepWrap.className = "morceau-keep";
|
||||
const keepTitle = document.createElement("span");
|
||||
@@ -121,6 +139,29 @@ export function init() {
|
||||
onOpen(() => send("/matrix/globalsettings/get"));
|
||||
send("/matrix/globalsettings/get");
|
||||
}
|
||||
// --- Fist indicators (hand 0 = Poing G -> charger, hand 1 = Poing D -> suivant) ---
|
||||
const fistHost = document.getElementById("morceau-fists");
|
||||
if (fistHost) {
|
||||
const fistFills = [];
|
||||
[["Poing G → charger"], ["Poing D → suivant"]].forEach((lbl, hand) => {
|
||||
const row = document.createElement("div");
|
||||
row.className = "morceau-fist";
|
||||
row.textContent = lbl[0];
|
||||
const fl = document.createElement("div");
|
||||
fl.className = "morceau-slot-fill";
|
||||
row.appendChild(fl);
|
||||
fistFills[hand] = fl;
|
||||
fistHost.appendChild(row);
|
||||
});
|
||||
on("/matrix/fistprogress", (args) => {
|
||||
const hand = Math.round(Number(args[0]));
|
||||
const prog = Number(args[1]) || 0;
|
||||
const fl = fistFills[hand];
|
||||
if (!fl) return;
|
||||
fl.style.width = (prog * 100) + "%";
|
||||
fl.classList.toggle("fired", prog >= 1);
|
||||
});
|
||||
}
|
||||
const bpm = document.getElementById("matrix-bpm");
|
||||
const bpmOut = document.getElementById("matrix-bpm-out");
|
||||
if (bpm) {
|
||||
|
||||
@@ -152,3 +152,11 @@ test("default pinch hold ms + setter", () => {
|
||||
assert.equal(matPinchHoldMs, 450);
|
||||
setPinchHoldMs(300);
|
||||
});
|
||||
|
||||
import { matFistThresh, setFistThresh } from "../public/control/js/matrix-state.js";
|
||||
test("default fist threshold + setter", () => {
|
||||
assert.equal(matFistThresh, 0.15);
|
||||
setFistThresh(0.3);
|
||||
assert.equal(matFistThresh, 0.3);
|
||||
setFistThresh(0.15);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user