From ea3ec65de1954502e75d6b2ddcf4a0a1c063c8be Mon Sep 17 00:00:00 2001 From: jahugg <jan@huggenberg.ch> Date: Wed, 1 Mar 2023 15:38:05 +0100 Subject: [PATCH] time delay selection --- src/main.js | 74 +++++++++++++++++++++++++++++++++++--------- src/styles/main.css | 17 ++++++++++ src/styles/main.less | 19 ++++++++++++ 3 files changed, 96 insertions(+), 14 deletions(-) diff --git a/src/main.js b/src/main.js index 70c3e69..e3eeb71 100644 --- a/src/main.js +++ b/src/main.js @@ -237,6 +237,13 @@ function buildPageContents(object) { linkEl.dataset.command = item.command; itemEl.appendChild(linkEl); + const progressEl = document.createElement("div"); + progressEl.className = "progress"; + linkEl.appendChild(progressEl); + progressEl.addEventListener("animationend", (event) => { + navigateToSelected(); + }); + if (item.label.toLowerCase() !== item.command.toLowerCase()) { const commandEl = document.createElement("div"); commandEl.className = "command"; @@ -282,14 +289,17 @@ function navigateToSelected() { if (currentItem) { const path = currentItem.getAttribute("href"); navigateToPath(path); - } else printLogMsg("no item selected to open"); + } else console.log("no item selected to open"); } // focus specific navigation item function focusNavigationItem(index, broadcast = true) { // unselect all items const navigationList = document.querySelectorAll("#navigation li"); - for (let item of navigationList) delete item.dataset.selected; + for (let item of navigationList) { + delete item.dataset.selected; + item.querySelector(".progress").style.animation = ""; + } // select requested element const navigationItem = document.querySelector( @@ -300,6 +310,8 @@ function focusNavigationItem(index, broadcast = true) { // broadcast focus event to other clients if (broadcast && socket.readyState === WebSocket.OPEN) socket.send(JSON.stringify({ type: "focus", value: index })); + + return navigationItem; } // focus next navigation item @@ -350,7 +362,7 @@ function focusClosestItem(targetY = window.innerHeight / 2) { } index++; } - focusNavigationItem(closestIndex); + return focusNavigationItem(closestIndex); } // moving up navigation tree @@ -382,7 +394,7 @@ function addMouseControls() { if (listItem) { // get childnode index let index = Array.from(listItem.parentNode.children).indexOf(listItem); - focusNavigationItem(index + 1); + let itemEl = focusNavigationItem(index + 1); } }); @@ -392,7 +404,10 @@ function addMouseControls() { if (listItem) { // unselect all items const navigationList = document.querySelectorAll("#navigation li"); - for (let item of navigationList) delete item.dataset.selected; + for (let item of navigationList) { + item.querySelector(".progress").style.animation = ""; + delete item.dataset.selected; + } } }); @@ -502,24 +517,27 @@ function addVoiceControls() { recognition.maxAlternatives = 1; recognition.start(); - printLogMsg("Voice > listening"); + console.log("Voice > listening"); recognition.onresult = function (event) { let command = event.results[0][0].transcript.toLowerCase(); let confidence = event.results[0][0].confidence; command = command.toLowerCase(); - printLogMsg(`Voice > Received "${command}" (${confidence.toFixed(2)})`); + console.log(`Voice > Received "${command}" (${confidence.toFixed(2)})`); if (commands.includes(command)) { let index = commands.indexOf(command); // get index of command in array let path = availableCommands[index].path; // get corresponding path in availableCommands array navigateToPath(path); - } else if (command === "select" || command === "okay") navigateToSelected(); - else if (command === "open") moveDownNavigationLevel(); - else if (command === "emergency call") + } else if (command.includes("select") || command.includes("okay")) + navigateToSelected(); + else if (command.includes("open")) moveDownNavigationLevel(); + else if (command.includes("emergency call")) navigateToPath("/menu/call/emergency"); - else if (command === "exit") navigateToPath("/"); + else if (command.includes("exit") || command.includes("home")) + navigateToPath("/"); + else if (command.includes("back")) moveUpNavigationLevel(); }; recognition.onspeechend = function () { @@ -527,7 +545,6 @@ function addVoiceControls() { setTimeout(() => { recognition.start(); - printLogMsg("Voice > listening"); }, "1000"); }; @@ -557,8 +574,10 @@ function addVoiceControls() { // =================== function addMotionControls() { let referenceY; - let sensitivity = 5000; + let sensitivity = 4000; let screenCenter = new Point(window.innerWidth / 2, window.innerHeight / 2); + let idleTimeout; + let idleDelay = 3000; // motion buffer stuff let motionBuffer = []; @@ -613,12 +632,39 @@ function addMotionControls() { bufferIterations++; averageYDiff = Math.abs(lastAverageY - averageY); if (averageYDiff > motionThreshold && referenceY !== undefined) { + // reseting reference point after a delay of holding still + clearTimeout(idleTimeout); + idleTimeout = setTimeout(() => { + referenceY = averageY; + + // start approaching new reference point + // somehow this currently only executes once... + let incrementValue = 0.001; + const intervalId = setInterval(() => { + if (referenceY < averageY) { + referenceY += incrementValue; + if (referenceY >= averageY) { + clearInterval(intervalId); + referenceY = averageY; // Ensure exact match with target + } + } else if (referenceY > averageY) { + referenceY -= incrementValue; + if (referenceY <= averageY) { + clearInterval(intervalId); + referenceY = averageY; // Ensure exact match with target + } + } else clearInterval(intervalId); + }, 100); + }, idleDelay); + lastAverageY = averageY; let targetY = averageY; targetY = (targetY - referenceY) * -sensitivity; drawMotion(targetY); - focusClosestItem(targetY); + let itemEl = focusClosestItem(targetY); + let progressEl = itemEl.querySelector(".progress"); + progressEl.style.animation = "progress 3s ease-out forwards"; } } } diff --git a/src/styles/main.css b/src/styles/main.css index 7648f41..1c87e4d 100644 --- a/src/styles/main.css +++ b/src/styles/main.css @@ -24,6 +24,14 @@ transform: translateX(0); } } +@keyframes progress { + from { + width: 0%; + } + to { + width: 100%; + } +} .link { position: relative; opacity: 0; @@ -33,6 +41,7 @@ margin-bottom: 0.4em; } .link a { + position: relative; color: inherit; text-decoration: none; border-bottom: solid 0.1em transparent; @@ -83,6 +92,14 @@ opacity: 1; background-position: center center; } +.link .progress { + height: 100%; + width: 0%; + position: absolute; + top: 0; + z-index: -100; + background: var(--color-grey-01); +} #canvas { display: block; width: 100%; diff --git a/src/styles/main.less b/src/styles/main.less index beddea4..f9a3b50 100644 --- a/src/styles/main.less +++ b/src/styles/main.less @@ -27,6 +27,15 @@ } } +@keyframes progress { + from { + width: 0%; + } + to { + width: 100%; + } +} + .link { position: relative; opacity: 0; @@ -37,6 +46,7 @@ } a { + position: relative; color: inherit; text-decoration: none; border-bottom: solid 0.1em transparent; @@ -95,6 +105,15 @@ background-position: center center; } } + + .progress { + height: 100%; + width: 0%; + position: absolute; + top: 0; + z-index: -100; + background: var(--color-grey-01); + } } #canvas { -- GitLab