From 4a960e3b03172dc597814a8d09c407aec20e2d94 Mon Sep 17 00:00:00 2001 From: James Hobin Date: Tue, 16 Apr 2024 12:32:46 -0400 Subject: [PATCH] Add toggle for recording video --- tools/spatialAnalytics/VideoToggle.js | 71 ++++++++++++++++++++ tools/spatialAnalytics/index.css | 65 +++++++++++++++++- tools/spatialAnalytics/index.html | 1 + tools/spatialAnalytics/index.js | 28 +++++--- tools/spatialAnalytics/sprites/no-video.png | Bin 0 -> 689 bytes tools/spatialAnalytics/sprites/video.png | Bin 0 -> 1034 bytes 6 files changed, 153 insertions(+), 12 deletions(-) create mode 100644 tools/spatialAnalytics/VideoToggle.js create mode 100644 tools/spatialAnalytics/sprites/no-video.png create mode 100644 tools/spatialAnalytics/sprites/video.png diff --git a/tools/spatialAnalytics/VideoToggle.js b/tools/spatialAnalytics/VideoToggle.js new file mode 100644 index 0000000..4f0b33f --- /dev/null +++ b/tools/spatialAnalytics/VideoToggle.js @@ -0,0 +1,71 @@ +export class VideoToggle { + constructor() { + this.toggleDivContainer = document.getElementById('toggleModeDivContainer'); + this.onToggle = null; + this.videoMode = true; + + this.create(); + this.add(); + } + + create() { + this.toggleDiv = document.createElement('div'); + this.toggleDiv.setAttribute('id', 'toggleModeDiv'); + this.toggleDiv.className = 'toggleModeDiv'; + + const toggleModeSlider = document.createElement('div'); + toggleModeSlider.setAttribute('id', 'toggleModeSlider'); + toggleModeSlider.className = 'toggleModeSlider'; + toggleModeSlider.classList.add('mode_right'); + this.toggleDiv.appendChild(toggleModeSlider); + + const noVideoIcon = document.createElement('div'); + noVideoIcon.setAttribute('id', 'captureNoVideo'); + noVideoIcon.classList.add('inactiveToggle', 'toggleIcon'); + + const noVideoImg = document.createElement('img'); + noVideoImg.src = 'sprites/no-video.png'; + noVideoIcon.appendChild(noVideoImg); + + this.toggleDiv.appendChild(noVideoIcon); + + const videoIcon = document.createElement('div'); + videoIcon.setAttribute('id', 'captureVideo'); + videoIcon.classList.add('activeToggle', 'toggleIcon'); + + const videoImg = document.createElement('img'); + videoImg.src = 'sprites/video.png'; + videoImg.style.paddingLeft = '2px'; + videoIcon.appendChild(videoImg); + + this.toggleDiv.appendChild(videoIcon); + + this.toggleDiv.addEventListener('pointerup', () => { + this.toggleMode(toggleModeSlider, noVideoIcon, videoIcon); + this.videoMode = !this.videoMode; + + if (this.onToggle) { + this.onToggle(this.videoMode); + } + }); + } + add() { + this.toggleDivContainer.appendChild(this.toggleDiv); + } + remove() { + if (this.toggleDiv.parentElement) { + this.toggleDivContainer.removeChild(this.toggleDiv); + } + } + toggleMode(toggleModeSlider, icon_left, icon_right) { + if (toggleModeSlider.classList.contains('mode_left')) { + toggleModeSlider.classList.replace('mode_left', 'mode_right'); + icon_right.classList.replace('inactiveToggle', 'activeToggle'); + icon_left.classList.replace('activeToggle', 'inactiveToggle'); + } else { + toggleModeSlider.classList.replace('mode_right', 'mode_left'); + icon_right.classList.replace('activeToggle', 'inactiveToggle'); + icon_left.classList.replace('inactiveToggle', 'activeToggle'); + } + } +} diff --git a/tools/spatialAnalytics/index.css b/tools/spatialAnalytics/index.css index a7e6d58..3efb883 100644 --- a/tools/spatialAnalytics/index.css +++ b/tools/spatialAnalytics/index.css @@ -20,7 +20,7 @@ img { } .iconContainer { - position: fixed; + position: absolute; transform: translateX(-50%); bottom: calc(230px - 66px); left: 50%; @@ -79,7 +79,7 @@ img { /** device is wide and touch-based */ @media (min-width: 800px) and (hover: none) { .iconContainer { - position: fixed; + position: absolute; left: auto; right: 66px; transform: none; @@ -141,3 +141,64 @@ img { .longTitle { text-overflow: ellipsis; } + +#toggleModeDivContainer { + position: absolute; + right: calc(50% + 108px); + bottom: calc(230px - 66px + 32px - 24px); +} + +.toggleModeDiv { + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + width: 80px; + height: 40px; + background-color: #00000080; + padding: 3px; + border-radius: 40px; +} +.toggleModeDiv.disabled { + pointer-events: none; +} +.toggleModeDiv.disabled p { + color: #4B4B4B; +} +.toggleModeDiv p { + font-family: OpenSans, sans-serif; + margin: auto; +} +.toggleModeSlider { + border-radius: 50%; + border: solid #ffffff 3px; + background-color: #FFFFFF50; + width: 40px; + height: 40px; + position: absolute; +} +.toggleIcon { + display: inline-block; + width: 32px; + height: 32px; +} +.toggleIcon > img { + width: 32px; + height: 32px; +} +.activeToggle { + opacity: 1; + transition: .4s; +} +.inactiveToggle { + opacity: .6; + transition: .4s; +} +.mode_left { + left: 0; + transition: .4s; +} +.mode_right { + left: 50%; + transition: .4s; +} diff --git a/tools/spatialAnalytics/index.html b/tools/spatialAnalytics/index.html index 09544fa..ac99e13 100644 --- a/tools/spatialAnalytics/index.html +++ b/tools/spatialAnalytics/index.html @@ -15,6 +15,7 @@
+
diff --git a/tools/spatialAnalytics/index.js b/tools/spatialAnalytics/index.js index 4c4fd6d..8d2b73a 100644 --- a/tools/spatialAnalytics/index.js +++ b/tools/spatialAnalytics/index.js @@ -1,9 +1,9 @@ /* global Envelope, SpatialInterface */ +import {VideoToggle} from './VideoToggle.js'; + const MINIMIZED_TOOL_WIDTH = 1200; const MINIMIZED_TOOL_HEIGHT = 600; -const RECORD_VIDEO = false; - let spatialInterface; let screenDimensions = null; @@ -41,6 +41,12 @@ const msIconBackground = document.querySelector('#analyticsMarkStepIcon'); const labelTitle = document.getElementById('labelTitle'); const label = document.getElementById('label'); +let videoEnabled = true; +const videoToggle = new VideoToggle(); +videoToggle.onToggle = (newVideoEnabled) => { + videoEnabled = newVideoEnabled; +}; + const RecordingState = { empty: 'empty', recording: 'recording', @@ -54,25 +60,27 @@ function setRecordingState(newState) { switch (recordingState) { case RecordingState.empty: recordingIcon.src = 'sprites/empty.png'; - markStepIcon.style.display = 'none'; + msIconBackground.style.display = 'none'; break; case RecordingState.recording: recordingIcon.src = 'sprites/recording.png'; - markStepIcon.style.display = 'inline'; + msIconBackground.style.display = ''; recIconBackground.classList.add('recording'); + videoToggle.remove(); break; case RecordingState.saving: recordingIcon.src = 'sprites/saving.svg'; - markStepIcon.style.display = 'none'; + msIconBackground.style.visibility = 'hidden'; recIconBackground.classList.add('recording'); + videoToggle.remove(); break; case RecordingState.done: recordingIcon.style.display = 'none'; - markStepIcon.style.display = 'none'; msIconBackground.style.display = 'none'; recIconBackground.style.display = 'none'; iconContainer.style.display = 'none'; + videoToggle.remove(); break; } } @@ -102,7 +110,7 @@ recordingIcon.addEventListener('pointerup', function() { spatialInterface.analyticsHydrate(data); } - if (RECORD_VIDEO) { + if (videoEnabled) { spatialInterface.startVirtualizerRecording(); } break; @@ -123,7 +131,7 @@ recordingIcon.addEventListener('pointerup', function() { }); } - if (RECORD_VIDEO) { + if (videoEnabled) { spatialInterface.stopVirtualizerRecording((baseUrl, recordingId, deviceId) => { setRecordingState(RecordingState.done); const urls = { @@ -195,7 +203,7 @@ envelope.onOpen(() => { let focused = false; envelope.onFocus(() => { focused = true; - iconContainer.style.display = 'block'; + envelopeContainer.style.display = 'block'; spatialInterface.analyticsFocus(); if (lastSetDisplayRegion.startTime !== startTime || lastSetDisplayRegion.endTime !== endTime) { @@ -214,7 +222,7 @@ envelope.onFocus(() => { envelope.onBlur(() => { focused = false; - iconContainer.style.display = 'none'; + envelopeContainer.style.display = 'none'; spatialInterface.analyticsBlur(); }); diff --git a/tools/spatialAnalytics/sprites/no-video.png b/tools/spatialAnalytics/sprites/no-video.png new file mode 100644 index 0000000000000000000000000000000000000000..2a9b1bcc95239c7c7bea337857976d4679e697e7 GIT binary patch literal 689 zcmV;i0#5yjP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10zOGZ zK~!jg?b@+!6fqFS@qcIng1k~Ha)cz10`WM|(C{)yKoXiD(ZCxa?zZ|UZY`anoY$Ti z`@(XcmsRUJ(cuB z>kN`!RqnU0Q%TFQ?k`D4HT$i=lpfGcU`iF#1MC5PaSyN>>IJrh=71?bOP~?J7SIx4 zF*FJo39SJZL372fDhs77#|O0lUrJgT>wevKZm!_5q~FGZgQSbh*->vW<&UK2+s>XU zd@>$jNe#3aPzA^y(565YB3nY6166@+0qp`*B{CA)4JZTB3tdTiuZ}=T97v`{)(P+h zcw*UX%o2DFe6QVT{b{}hF2}+>Vg`b*Gtdj_0)oH&(HiOoLQIdR6?6dJ;siomBP$v@ z0B>0Lbli#T)fe_!4yahfu&-h3n5HNoyw`IZl`}x>$#)E#75kP=L;1h7}exfl^ z$S7b+C^P~Y4NM7xdXcSwDIrh~ashm%9WccWwIUO+*I$SWYC(E{1Mm)58TQ(tl|P^h z`F@zsH_myGodGZKZjYxMbXUNx&>lUVslID-=&pfXpsj$GyO3tkT+wS|LGP`W6?(Pp z++0EH{bcPMyt^!o=j_$`RKePtW-rhJotzygDOfr)5CyD(77a&~7Mz;?hz6EGL#ID- z(3Zd)w8r*(2wY{{s0J XPGoUt{TiEA00000NkvXXu0mjftjQ}A literal 0 HcmV?d00001 diff --git a/tools/spatialAnalytics/sprites/video.png b/tools/spatialAnalytics/sprites/video.png new file mode 100644 index 0000000000000000000000000000000000000000..fa26ec06599c5f022849ab90c6a792d0970d80f3 GIT binary patch literal 1034 zcmeAS@N?(olHy`uVBq!ia0vp^(}8#z2OE&Qd|2uZkm4-xh%9Dc;1&X5#!GkW{xC2w z@9}hT45^s&_U`>a;XoPpkNSP@FEx6zUTBPH3~JoS?0tc615+~l4aP8ql?N^`hBWYt zyQcGGe6rqs`rXenPgrN{Ha|J@?{wAO<;BIqogY$OaAxf4@s@ZjbZke9pj?K9U~YTuTJa+z&EX6k=D z({b<355Et0wMtyyqmw7U_l>&r^)GLq=Ux83=RB+Q^^#K0d&}Rhu;2Y%U-8({-;>H% z%BE~v@4Wxw@yzU1;U9|RQex(W-ik{8d;9#i$vTJkeC*z`!mI3(h_c9|EjA@r z4^_S@TNR#pG3>qn+qX6ig^GTc*6qFZMC0W4dCxZKK9*WpUzvRD->$bZ)2CbVKd*Yh zd7-EK;{|v1ST-x$3+j)P_T2yYeR4ufPk82XnSak>&FYt#Yrea%S+Dr}{Q&pO=X>Q& zf6bTE<$8Q^(XrFCiNvZucK7Yvj_;7$UwUh8B;TZ(6CL}S?(A5WJolUK#n`Bn>CER; zI}3d;hQ3p(p3SIiye>0(nQPgkC)xM8&DT|0c<=7Mb$ZKh`)`MKJbP;McJ~MVONRxQ z6`s9p^<6%3otD_6xk=A+=WhF4KWm%Y>r3yx6~-CvD73Ac{m$+8{$w5QV?UjbrfvMb zSm5u&q!*kyL4wya=HKCoNk6i_-Zf@9YjTG5=_@&6f}(|MFP~#s9lyHg&$0!f%ax`X zZm?T>$*-%gZ0*!5ck(}$$KIM7&_7uwjBicM^0`VD+yyD_EBd^D9X0-PNMgFdG1Z