diff --git a/src/main.js b/src/main.js index e93a03c601c1992185e1abac48ce596bb75bec51..43494a1ce856e60af7d283829e3624a56839b65b 100644 --- a/src/main.js +++ b/src/main.js @@ -5,8 +5,8 @@ const config = { controls: { mouse: true, button: true, - voice: true, - motion: false, + voice: false, + motion: true, }, }; @@ -579,8 +579,10 @@ function addVoiceControls() { else if (command.includes("exit") || command.includes("home")) navigateToPath("/"); else if (command.includes("back")) moveUpNavigationLevel(); - else if (command.includes("next") || command.includes("down")) focusNextNavigationItem(); - else if (command.includes("previous") || command.includes("up")) focusPreviousNavigationItem(); + else if (command.includes("next") || command.includes("down")) + focusNextNavigationItem(); + else if (command.includes("previous") || command.includes("up")) + focusPreviousNavigationItem(); }; // updating voice command list @@ -605,7 +607,7 @@ function addVoiceControls() { // =================== function addMotionControls() { let referenceY; // current zero reference point - let sensitivity = 5000; // change motion sensitivity + let factor = -5000; // factor to map sensor data to pixels (sensitivity) let screenCenter = new Point(window.innerWidth / 2, window.innerHeight / 2); let idleTimeout; let intervalId; @@ -616,12 +618,16 @@ function addMotionControls() { // motion buffer stuff let motionBuffer = []; // motion value buffer + let averageY = 0; let lastAverageY = 0; // last average of buffer values let bufferIterations = 0; // how many times buffer has been iterated + let targetPositionInPx = 0; + let currentPositionInPx = 0; + let lastPositionInPx = 0; const bufferIterationLimit = 5; // iterations before new average calculation is triggered const bufferLength = 10; // length of value buffer - const noiseThreshold = 0.02; // threshold to avoid general sensor noise - const inactiveThreshold = 50; // threshold to define inactive area in the reference + const noiseThreshold = 40; // threshold in pixel to avoid sensor noise + const inactiveThreshold = 50; // threshold in pixel to define inactive area around the reference // create canvas element for motion visualization const canvasEl = document.createElement("canvas"); @@ -653,83 +659,89 @@ function addMotionControls() { // write quaternion y value into motion buffer motionBuffer.push(y); - // wait for buffer to collect enough datapoints + // on first iteration + if (!referenceY) { + referenceY = y; // set initial reference point + averageY = y; // set initial last average point + lastAverageY = y; // set initial last average point + lastPositionInPx = (averageY - referenceY) * factor; + } + + // calculate positions in pixels + targetPositionInPx = (averageY - referenceY) * factor; // target position in pixels + currentPositionInPx = + lastPositionInPx + (targetPositionInPx - lastPositionInPx) * 0.1; // move towards target + currentPositionInPx = helpers.clamp(currentPositionInPx, -400, 400); // clamp to reasonable range + lastPositionInPx = currentPositionInPx; // save current position for later + + // draw sensor motion for debugging + if (drawMotionFlag) drawMotion(currentPositionInPx); + + // select item at target position if conditions are met + let averageDiffInPx = Math.abs((lastAverageY - averageY) * factor); + if (averageDiffInPx > noiseThreshold) { + let itemEl = focusClosestItem(currentPositionInPx); + lastAverageY = averageY; // save averageY for later comparison + } + + // fill buffer with datapoints if (motionBuffer.length > bufferLength) { motionBuffer.shift(); // limit buffer length // calculate the new average value as soon as bufferiterationlimit reached if (bufferIterations > bufferIterationLimit) { // calculate average value of values - let averageY = - motionBuffer.reduce((a, b) => a + b) / motionBuffer.length; - - // on first iteration - if (!referenceY) { - referenceY = averageY; // set initial reference point - lastAverageY = averageY; // set initial last avaerage point - } + averageY = motionBuffer.reduce((a, b) => a + b) / motionBuffer.length; - // calculate target position - let targetY = averageY; - targetY = (targetY - referenceY) * -sensitivity; + // select item at target position if conditions are met + let averageDiffInPx = Math.abs((lastAverageY - averageY) * factor); + let diffToReferenceInPx = Math.abs((averageY - referenceY) * factor); - // draw sensor motion for debugging - if (drawMotionFlag) drawMotion(targetY); - - // select item at target position - let averageYDiff = Math.abs(lastAverageY - averageY); - let distanceToReference = Math.abs(targetY); - - if ( - averageYDiff > noiseThreshold && // exeeding noise threshold - distanceToReference > inactiveThreshold // exeeding min distance to reference - ) { + if (false) { + let itemEl = focusClosestItem(currentPositionInPx); // clear timeout monitoring if pointer is within reasonable distance - if (distanceToReference < 400) { + if (diffToReferenceInPx < 400) { clearTimeout(idleTimeout); - // reseting reference point after a delay of holding still + // resetting reference point after a delay of holding still if (!intervalRunning) idleTimeout = setTimeout(() => { - printLogMsg("starting timer"); + referenceY = y; + + printLogMsg(`${referenceY}:${y}`); // start approaching new reference point - let incrementValue = 0.01; - intervalId = setInterval(() => { - intervalRunning = true; - if (referenceY < averageY) { - printLogMsg("down"); - referenceY += incrementValue; - if (referenceY >= averageY) { - referenceY = averageY; // Ensure exact match with target - stopInterval(intervalId); - } - } else if (referenceY > averageY) { - printLogMsg("up"); - referenceY -= incrementValue; - if (referenceY <= averageY) { - referenceY = averageY; // Ensure exact match with target - stopInterval(intervalId); - } - } else stopInterval(intervalId); - }, 100); + // intervalId = setInterval(() => { + // printLogMsg("run interval"); + // intervalRunning = true; + // let absoluteDiff = Math.abs(referenceY - averageY); + // let incrementValue = absoluteDiff * 0.001; + // printLogMsg(`${referenceY}:${averageY}`); + + // if (absoluteDiff < 0.1) { + // printLogMsg("stop interval"); + // referenceY = averageY; // Ensure exact match with target + // clearInterval(intervalId); + // intervalRunning = false; + // } else if (referenceY < averageY) + // referenceY += incrementValue; + // else if (referenceY > averageY) referenceY -= incrementValue; + // }, 100); }, idleDelay); } // select item if ouside of center save area - if (distanceToReference > inactiveThreshold) { - let targetY = averageY; - targetY = (targetY - referenceY) * -sensitivity; - let itemEl = focusClosestItem(targetY); - - // trigger autoselection via motion - if (autoSelect) { - let progressEl = itemEl.querySelector(".progress"); - progressEl.style.animation = "progress 2s ease-out forwards"; - } - } else { - printLogMsg("deselect all"); - deselectAllItems(); - } + // if (distanceInPx > inactiveThreshold) { + // let targetInPx = (averageY - referenceY) * factor; + // let itemEl = focusClosestItem(targetInPx); + + // // trigger autoselection via motion + // if (autoSelect) { + // let progressEl = itemEl.querySelector(".progress"); + // progressEl.style.animation = "progress 2s ease-out forwards"; + // } + // } else { + // deselectAllItems(); + // } lastAverageY = averageY; // save averageY for later comparison } @@ -737,12 +749,6 @@ function addMotionControls() { } bufferIterations++; } - - function stopInterval(id) { - printLogMsg("interval stopped"); - clearInterval(id); - intervalRunning = false; - } } function drawMotion(y) {