diff --git a/src/main.js b/src/main.js index 43494a1ce856e60af7d283829e3624a56839b65b..28c2c7b5871a434019a34c71b81ac6965580f91f 100644 --- a/src/main.js +++ b/src/main.js @@ -5,7 +5,7 @@ const config = { controls: { mouse: true, button: true, - voice: false, + voice: true, motion: true, }, }; @@ -30,19 +30,19 @@ const navigation = { label: "Emergency", command: "emergency", path: "/menu/call/emergency", - message: "Calling Emergency", + message: "👍 Calling Emergency", }, contacta: { label: "Flute Inc.", command: "contact a", path: "/menu/call/contacta", - message: "Calling Flute Inc.", + message: "👍 Calling Flute Inc.", }, contactb: { label: "Brays AG", command: "contact b", path: "/menu/call/contactb", - message: "Calling Brays AG", + message: "👍 Calling Brays AG", }, }, }, @@ -55,19 +55,19 @@ const navigation = { label: "Daily", command: "daily", path: "/menu/check/daily", - message: "Displaying Daily Checklist", + message: "👍 Displaying Daily Checklist", }, weekly: { label: "Weekly", command: "weekly", path: "/menu/check/weekly", - message: "Displaying Weekly Checklist", + message: "👍 Displaying Weekly Checklist", }, monthly: { label: "Monthly", command: "monthly", path: "/menu/check/monthly", - message: "Displaying Monthly Checklist", + message: "👍 Displaying Monthly Checklist", }, }, }, @@ -80,19 +80,19 @@ const navigation = { label: "Record", command: "record", path: "/menu/apps/record", - message: "Opening Recording App", + message: "👍 Opening Recording App", }, breakout: { label: "Breakout", command: "breakout", path: "/menu/apps/breakout", - message: "Opening Breakout App", + message: "👍 Opening Breakout App", }, statistics: { label: "Statistics", command: "statistics", path: "/menu/apps/statistics", - message: "Opening Statistics App", + message: "👍 Opening Statistics App", }, }, }, @@ -477,7 +477,8 @@ function addButtonControls() { event.code === "ArrowUp" || event.code === "ArrowRight" || event.code === "ArrowDown" || - event.code === "ArrowLeft" + event.code === "ArrowLeft" || + event.code === "ShiftRight" ) event.preventDefault(); @@ -485,7 +486,7 @@ function addButtonControls() { if (event.code === "Tab" || event.code === "ArrowDown") focusNextNavigationItem(); else if (event.code === "ArrowUp") focusPreviousNavigationItem(); - else if (event.code === "Enter") navigateToSelected(); + else if (event.code === "Enter" || event.code === "ShiftRight") navigateToSelected(); else if (event.code === "ArrowRight") moveDownNavigationLevel(); else if (event.code === "ArrowLeft" || event.code === "Escape") moveUpNavigationLevel(); @@ -574,7 +575,7 @@ function addVoiceControls() { } else if (command.includes("select") || command.includes("okay")) navigateToSelected(); else if (command.includes("open")) moveDownNavigationLevel(); - else if (command.includes("emergency call")) + else if (command.includes("emergency")) navigateToPath("/menu/call/emergency"); else if (command.includes("exit") || command.includes("home")) navigateToPath("/"); @@ -610,10 +611,8 @@ function addMotionControls() { 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; - let intervalRunning = false; - let idleDelay = 5000; //idle time before reseting reference point - let autoSelect = false; // selecting items with time delay + let idleDelay = 4000; //idle time before reseting reference point + let autoSelect = true; // selecting items with time delay let drawMotionFlag = true; // draw motion values for debugging // motion buffer stuff @@ -626,8 +625,9 @@ function addMotionControls() { let lastPositionInPx = 0; const bufferIterationLimit = 5; // iterations before new average calculation is triggered const bufferLength = 10; // length of value buffer - const noiseThreshold = 40; // threshold in pixel to avoid sensor noise - const inactiveThreshold = 50; // threshold in pixel to define inactive area around the reference + const noiseThreshold = 30; // threshold in pixel to avoid sensor noise + const innerLimit = 80; // threshold in pixel to define inactive area around the reference + const outerLimit = 400; // create canvas element for motion visualization const canvasEl = document.createElement("canvas"); @@ -671,7 +671,11 @@ function addMotionControls() { 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 + currentPositionInPx = helpers.clamp( + currentPositionInPx, + -outerLimit, + outerLimit + ); // clamp to reasonable range lastPositionInPx = currentPositionInPx; // save current position for later // draw sensor motion for debugging @@ -679,10 +683,27 @@ function addMotionControls() { // 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 - } + let distFromCenter = Math.abs(currentPositionInPx); + // if position is withing limits + if (distFromCenter < outerLimit && distFromCenter > innerLimit) { + // movement is not noise + if (averageDiffInPx > noiseThreshold) { + let itemEl = focusClosestItem(currentPositionInPx); + lastAverageY = averageY; // save averageY for later comparison + + // trigger autoselection via motion + if (autoSelect) { + let progressEl = itemEl.querySelector(".progress"); + progressEl.style.animation = "progress 2s ease-out forwards"; + } + + // handle auto reseting of reference point + clearTimeout(idleTimeout); + idleTimeout = setTimeout(() => { + referenceY = averageY; + }, idleDelay); + } + } else deselectAllItems(); // fill buffer with datapoints if (motionBuffer.length > bufferLength) { @@ -690,61 +711,7 @@ function addMotionControls() { // calculate the new average value as soon as bufferiterationlimit reached if (bufferIterations > bufferIterationLimit) { - // calculate average value of values averageY = motionBuffer.reduce((a, b) => a + b) / motionBuffer.length; - - // select item at target position if conditions are met - let averageDiffInPx = Math.abs((lastAverageY - averageY) * factor); - let diffToReferenceInPx = Math.abs((averageY - referenceY) * factor); - - if (false) { - let itemEl = focusClosestItem(currentPositionInPx); - // clear timeout monitoring if pointer is within reasonable distance - if (diffToReferenceInPx < 400) { - clearTimeout(idleTimeout); - - // resetting reference point after a delay of holding still - if (!intervalRunning) - idleTimeout = setTimeout(() => { - referenceY = y; - - printLogMsg(`${referenceY}:${y}`); - // start approaching new reference point - // 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 (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 - } bufferIterations = 0; } bufferIterations++; @@ -758,19 +725,23 @@ function addMotionControls() { ctx.clearRect(0, 0, canvasEl.width, canvasEl.height); + // save zone + ctx.beginPath(); + ctx.arc(screenCenter.x, screenCenter.y, innerLimit, 0, 2 * Math.PI); + ctx.strokeStyle = "rgba(255, 0, 255, .6)"; + ctx.lineWidth = 3; + ctx.stroke(); + ctx.closePath(); + + // outer limit ctx.beginPath(); - ctx.arc( - screenCenter.x, - screenCenter.y, - inactiveThreshold, - 0, - 2 * Math.PI - ); + ctx.arc(screenCenter.x, screenCenter.y, outerLimit, 0, 2 * Math.PI); ctx.strokeStyle = "rgba(255, 0, 255, .6)"; ctx.lineWidth = 3; ctx.stroke(); ctx.closePath(); + // distance ctx.beginPath(); ctx.moveTo(screenCenter.x, screenCenter.y); ctx.lineTo(screenCenter.x, screenCenter.y + y); @@ -779,6 +750,7 @@ function addMotionControls() { ctx.stroke(); ctx.closePath(); + // target ctx.beginPath(); ctx.arc(screenCenter.x, screenCenter.y + y, pointSize, 0, 2 * Math.PI); ctx.fillStyle = "rgba(255, 0, 255, .6)";