brilliantsole 0.0.25 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +16 -10
  2. package/assets/3d/rightHand.glb +0 -0
  3. package/assets/images/ukaton-pressure-0.svg +9 -0
  4. package/assets/images/ukaton-pressure-1.svg +9 -0
  5. package/assets/images/ukaton-pressure-10.svg +9 -0
  6. package/assets/images/ukaton-pressure-11.svg +9 -0
  7. package/assets/images/ukaton-pressure-12.svg +9 -0
  8. package/assets/images/ukaton-pressure-13.svg +9 -0
  9. package/assets/images/ukaton-pressure-14.svg +9 -0
  10. package/assets/images/ukaton-pressure-15.svg +9 -0
  11. package/assets/images/ukaton-pressure-2.svg +9 -0
  12. package/assets/images/ukaton-pressure-3.svg +9 -0
  13. package/assets/images/ukaton-pressure-4.svg +9 -0
  14. package/assets/images/ukaton-pressure-5.svg +9 -0
  15. package/assets/images/ukaton-pressure-6.svg +9 -0
  16. package/assets/images/ukaton-pressure-7.svg +9 -0
  17. package/assets/images/ukaton-pressure-8.svg +9 -0
  18. package/assets/images/ukaton-pressure-9.svg +9 -0
  19. package/assets/images/ukaton-right-insole.svg +798 -0
  20. package/build/brilliantsole.cjs +255 -119
  21. package/build/brilliantsole.cjs.map +1 -1
  22. package/build/brilliantsole.js +283 -140
  23. package/build/brilliantsole.js.map +1 -1
  24. package/build/brilliantsole.ls.js +210 -103
  25. package/build/brilliantsole.ls.js.map +1 -1
  26. package/build/brilliantsole.min.js +1 -1
  27. package/build/brilliantsole.min.js.map +1 -1
  28. package/build/brilliantsole.module.d.ts +76 -60
  29. package/build/brilliantsole.module.js +282 -140
  30. package/build/brilliantsole.module.js.map +1 -1
  31. package/build/brilliantsole.module.min.d.ts +76 -60
  32. package/build/brilliantsole.module.min.js +1 -1
  33. package/build/brilliantsole.module.min.js.map +1 -1
  34. package/build/brilliantsole.node.module.d.ts +75 -60
  35. package/build/brilliantsole.node.module.js +254 -119
  36. package/build/brilliantsole.node.module.js.map +1 -1
  37. package/build/dts/BS.d.ts +2 -2
  38. package/build/dts/Device.d.ts +11 -7
  39. package/build/dts/DeviceManager.d.ts +1 -0
  40. package/build/dts/InformationManager.d.ts +6 -5
  41. package/build/dts/connection/BaseConnectionManager.d.ts +2 -0
  42. package/build/dts/connection/ClientConnectionManager.d.ts +4 -0
  43. package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +1 -0
  44. package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +1 -0
  45. package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +1 -0
  46. package/build/dts/devicePair/DevicePair.d.ts +14 -10
  47. package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +8 -4
  48. package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +2 -2
  49. package/build/dts/server/BaseClient.d.ts +1 -0
  50. package/build/dts/utils/CenterOfPressureHelper.d.ts +2 -2
  51. package/build/dts/utils/MathUtils.d.ts +2 -0
  52. package/build/index.d.ts +76 -60
  53. package/build/index.node.d.ts +75 -60
  54. package/examples/3d/script.js +90 -17
  55. package/examples/balance/script.js +2 -1
  56. package/examples/basic/index.html +21 -2
  57. package/examples/basic/script.js +17 -3
  58. package/examples/bottango/index.html +11 -1
  59. package/examples/bottango/script.js +2 -2
  60. package/examples/center-of-pressure/index.html +114 -114
  61. package/examples/center-of-pressure/script.js +1 -1
  62. package/examples/device-pair/index.html +58 -58
  63. package/examples/device-pair/script.js +12 -8
  64. package/examples/gloves/index.html +116 -0
  65. package/examples/gloves/scene.html +124 -0
  66. package/examples/gloves/script.js +615 -0
  67. package/examples/graph/index.html +11 -1
  68. package/examples/graph/script.js +2 -2
  69. package/examples/pressure/index.html +180 -12
  70. package/examples/pressure/script.js +144 -7
  71. package/examples/recording/index.html +191 -183
  72. package/examples/server/index.html +11 -1
  73. package/examples/server/script.js +6 -3
  74. package/examples/ukaton-firmware-update/index.html +20 -0
  75. package/examples/ukaton-firmware-update/manifest.json +11 -0
  76. package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
  77. package/examples/webxr/script.js +3 -3
  78. package/package.json +1 -1
  79. package/src/BS.ts +3 -8
  80. package/src/Device.ts +41 -8
  81. package/src/DeviceInformationManager.ts +4 -2
  82. package/src/DeviceManager.ts +10 -1
  83. package/src/FileTransferManager.ts +1 -1
  84. package/src/FirmwareManager.ts +1 -1
  85. package/src/InformationManager.ts +24 -7
  86. package/src/TfliteManager.ts +1 -1
  87. package/src/connection/BaseConnectionManager.ts +23 -6
  88. package/src/connection/ClientConnectionManager.ts +13 -1
  89. package/src/connection/bluetooth/BluetoothConnectionManager.ts +6 -1
  90. package/src/connection/bluetooth/NobleConnectionManager.ts +8 -1
  91. package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +5 -1
  92. package/src/devicePair/DevicePair.ts +53 -27
  93. package/src/devicePair/DevicePairPressureSensorDataManager.ts +51 -23
  94. package/src/devicePair/DevicePairSensorDataManager.ts +5 -5
  95. package/src/scanner/NobleScanner.ts +5 -3
  96. package/src/sensor/BarometerSensorDataManager.ts +1 -1
  97. package/src/sensor/MotionSensorDataManager.ts +1 -1
  98. package/src/sensor/PressureSensorDataManager.ts +13 -8
  99. package/src/sensor/SensorConfigurationManager.ts +3 -3
  100. package/src/sensor/SensorDataManager.ts +1 -1
  101. package/src/server/BaseClient.ts +43 -2
  102. package/src/server/BaseServer.ts +149 -39
  103. package/src/server/udp/UDPServer.ts +1 -1
  104. package/src/server/websocket/WebSocketClient.ts +3 -2
  105. package/src/server/websocket/WebSocketServer.ts +1 -1
  106. package/src/utils/CenterOfPressureHelper.ts +5 -5
  107. package/src/utils/MathUtils.ts +31 -1
  108. package/src/utils/ParseUtils.ts +1 -1
  109. package/src/utils/checksum.ts +1 -1
  110. package/src/utils/mcumgr.js +1 -1
@@ -12,7 +12,6 @@
12
12
  }
13
13
  .insole {
14
14
  position: relative;
15
- height: 500px;
16
15
  }
17
16
  img:not(.overlay) {
18
17
  position: relative;
@@ -20,7 +19,9 @@
20
19
  img.overlay {
21
20
  position: absolute;
22
21
  }
23
- .insole.left .viz {
22
+ .insole.left * [data-pressure],
23
+ .insole.left * [data-haptics],
24
+ .insole.left * img {
24
25
  -webkit-transform: scaleX(-1);
25
26
  transform: scaleX(-1);
26
27
  }
@@ -45,47 +46,180 @@
45
46
  [data-haptics] {
46
47
  /* background-color: blue;*/
47
48
  }
48
- [data-pressure="0"] {
49
+
50
+ /* Default pressure images */
51
+ .viz:not(.ukaton) [data-pressure="0"] {
49
52
  -webkit-mask-image: url(../../assets/images/pressure-0.svg);
50
53
  mask-image: url(../../assets/images/pressure-0.svg);
51
54
  }
52
- [data-pressure="1"] {
55
+ .viz:not(.ukaton) [data-pressure="1"] {
53
56
  -webkit-mask-image: url(../../assets/images/pressure-1.svg);
54
57
  mask-image: url(../../assets/images/pressure-1.svg);
55
58
  }
56
- [data-pressure="2"] {
59
+ .viz:not(.ukaton) [data-pressure="2"] {
57
60
  -webkit-mask-image: url(../../assets/images/pressure-2.svg);
58
61
  mask-image: url(../../assets/images/pressure-2.svg);
59
62
  }
60
- [data-pressure="3"] {
63
+ .viz:not(.ukaton) [data-pressure="3"] {
61
64
  -webkit-mask-image: url(../../assets/images/pressure-3.svg);
62
65
  mask-image: url(../../assets/images/pressure-3.svg);
63
66
  }
64
- [data-pressure="4"] {
67
+ .viz:not(.ukaton) [data-pressure="4"] {
65
68
  -webkit-mask-image: url(../../assets/images/pressure-4.svg);
66
69
  mask-image: url(../../assets/images/pressure-4.svg);
67
70
  }
68
- [data-pressure="5"] {
71
+ .viz:not(.ukaton) [data-pressure="5"] {
69
72
  -webkit-mask-image: url(../../assets/images/pressure-5.svg);
70
73
  mask-image: url(../../assets/images/pressure-5.svg);
71
74
  }
72
- [data-pressure="6"] {
75
+ .viz:not(.ukaton) [data-pressure="6"] {
73
76
  -webkit-mask-image: url(../../assets/images/pressure-6.svg);
74
77
  mask-image: url(../../assets/images/pressure-6.svg);
75
78
  }
76
- [data-pressure="7"] {
79
+ .viz:not(.ukaton) [data-pressure="7"] {
77
80
  -webkit-mask-image: url(../../assets/images/pressure-7.svg);
78
81
  mask-image: url(../../assets/images/pressure-7.svg);
79
82
  }
83
+ .viz:not(.ukaton) [data-pressure="8"] {
84
+ display: none;
85
+ }
86
+ .viz:not(.ukaton) [data-pressure="9"] {
87
+ display: none;
88
+ }
89
+ .viz:not(.ukaton) [data-pressure="10"] {
90
+ display: none;
91
+ }
92
+ .viz:not(.ukaton) [data-pressure="11"] {
93
+ display: none;
94
+ }
95
+ .viz:not(.ukaton) [data-pressure="12"] {
96
+ display: none;
97
+ }
98
+ .viz:not(.ukaton) [data-pressure="13"] {
99
+ display: none;
100
+ }
101
+ .viz:not(.ukaton) [data-pressure="14"] {
102
+ display: none;
103
+ }
104
+ .viz:not(.ukaton) [data-pressure="15"] {
105
+ display: none;
106
+ }
107
+
108
+ /* Ukaton-specific pressure images */
109
+ .viz.ukaton [data-pressure="0"] {
110
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-0.svg);
111
+ mask-image: url(../../assets/images/ukaton-pressure-0.svg);
112
+ }
113
+ .viz.ukaton [data-pressure="1"] {
114
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-1.svg);
115
+ mask-image: url(../../assets/images/ukaton-pressure-1.svg);
116
+ }
117
+ .viz.ukaton [data-pressure="2"] {
118
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-2.svg);
119
+ mask-image: url(../../assets/images/ukaton-pressure-2.svg);
120
+ }
121
+ .viz.ukaton [data-pressure="3"] {
122
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-3.svg);
123
+ mask-image: url(../../assets/images/ukaton-pressure-3.svg);
124
+ }
125
+ .viz.ukaton [data-pressure="4"] {
126
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-4.svg);
127
+ mask-image: url(../../assets/images/ukaton-pressure-4.svg);
128
+ }
129
+ .viz.ukaton [data-pressure="5"] {
130
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-5.svg);
131
+ mask-image: url(../../assets/images/ukaton-pressure-5.svg);
132
+ }
133
+ .viz.ukaton [data-pressure="6"] {
134
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-6.svg);
135
+ mask-image: url(../../assets/images/ukaton-pressure-6.svg);
136
+ }
137
+ .viz.ukaton [data-pressure="7"] {
138
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-7.svg);
139
+ mask-image: url(../../assets/images/ukaton-pressure-7.svg);
140
+ }
141
+ .viz.ukaton [data-pressure="8"] {
142
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-8.svg);
143
+ mask-image: url(../../assets/images/ukaton-pressure-8.svg);
144
+ }
145
+ .viz.ukaton [data-pressure="9"] {
146
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-9.svg);
147
+ mask-image: url(../../assets/images/ukaton-pressure-9.svg);
148
+ }
149
+ .viz.ukaton [data-pressure="10"] {
150
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-10.svg);
151
+ mask-image: url(../../assets/images/ukaton-pressure-10.svg);
152
+ }
153
+ .viz.ukaton [data-pressure="11"] {
154
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-11.svg);
155
+ mask-image: url(../../assets/images/ukaton-pressure-11.svg);
156
+ }
157
+ .viz.ukaton [data-pressure="12"] {
158
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-12.svg);
159
+ mask-image: url(../../assets/images/ukaton-pressure-12.svg);
160
+ }
161
+ .viz.ukaton [data-pressure="13"] {
162
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-13.svg);
163
+ mask-image: url(../../assets/images/ukaton-pressure-13.svg);
164
+ }
165
+ .viz.ukaton [data-pressure="14"] {
166
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-14.svg);
167
+ mask-image: url(../../assets/images/ukaton-pressure-14.svg);
168
+ }
169
+ .viz.ukaton [data-pressure="15"] {
170
+ -webkit-mask-image: url(../../assets/images/ukaton-pressure-15.svg);
171
+ mask-image: url(../../assets/images/ukaton-pressure-15.svg);
172
+ }
80
173
 
81
- [data-haptics="front"] {
174
+ .viz [data-haptics="front"] {
82
175
  -webkit-mask-image: url(../../assets/images/haptics-front.svg);
83
176
  mask-image: url(../../assets/images/haptics-front.svg);
84
177
  }
85
- [data-haptics="rear"] {
178
+ .viz [data-haptics="rear"] {
86
179
  -webkit-mask-image: url(../../assets/images/haptics-rear.svg);
87
180
  mask-image: url(../../assets/images/haptics-rear.svg);
88
181
  }
182
+ .viz:not(.ukaton) [data-haptics] {
183
+ display: none;
184
+ }
185
+
186
+ .viz {
187
+ position: relative;
188
+ height: 500px;
189
+ }
190
+
191
+ .center,
192
+ .devicePairCenter {
193
+ position: absolute;
194
+ left: 0%;
195
+ bottom: 0%;
196
+ width: 20px;
197
+ height: 20px;
198
+ opacity: 0;
199
+ z-index: 2;
200
+ }
201
+ .center > div,
202
+ .devicePairCenter > div {
203
+ border-radius: 50%;
204
+ position: relative;
205
+ top: 50%;
206
+ left: -50%;
207
+ width: 100%;
208
+ height: 100%;
209
+ }
210
+ .center > div {
211
+ background-color: green;
212
+ }
213
+ .devicePairCenter > div {
214
+ background-color: orange;
215
+ }
216
+
217
+ .viz:not(.ukaton) img.ukaton {
218
+ display: none;
219
+ }
220
+ .viz.ukaton img:not(.ukaton) {
221
+ display: none;
222
+ }
89
223
  </style>
90
224
  <body>
91
225
  <nav>
@@ -115,6 +249,24 @@
115
249
  <button id="addDevice">add device</button>
116
250
  </p>
117
251
 
252
+ <p>
253
+ <label>
254
+ pressure visualization
255
+ <select id="pressureVisualizationMode">
256
+ <optgroup label="pressure visualization mode"></optgroup>
257
+ </select>
258
+ </label>
259
+ </p>
260
+
261
+ <p>
262
+ <label>
263
+ center of pressure visualization
264
+ <select id="centerOfPressureVisualizationMode">
265
+ <optgroup label="center of pressure visualization mode"></optgroup>
266
+ </select>
267
+ </label>
268
+ </p>
269
+
118
270
  <div id="insoles"></div>
119
271
 
120
272
  <template id="insoleTemplate">
@@ -125,6 +277,12 @@
125
277
  <button class="togglePressureData" disabled>enable pressure data</button>
126
278
  </p>
127
279
  <div class="viz">
280
+ <div class="center">
281
+ <div></div>
282
+ </div>
283
+ <div class="devicePairCenter">
284
+ <div></div>
285
+ </div>
128
286
  <div data-pressure="0"></div>
129
287
  <div data-pressure="1"></div>
130
288
  <div data-pressure="2"></div>
@@ -134,10 +292,20 @@
134
292
  <div data-pressure="6"></div>
135
293
  <div data-pressure="7"></div>
136
294
 
295
+ <div data-pressure="8" class="ukaton"></div>
296
+ <div data-pressure="9" class="ukaton"></div>
297
+ <div data-pressure="10" class="ukaton"></div>
298
+ <div data-pressure="11" class="ukaton"></div>
299
+ <div data-pressure="12" class="ukaton"></div>
300
+ <div data-pressure="13" class="ukaton"></div>
301
+ <div data-pressure="14" class="ukaton"></div>
302
+ <div data-pressure="15" class="ukaton"></div>
303
+
137
304
  <div data-haptics="front"></div>
138
305
  <div data-haptics="rear"></div>
139
306
 
140
307
  <img src="../../assets/images/right-insole.svg" />
308
+ <img class="ukaton" src="../../assets/images/ukaton-right-insole.svg" />
141
309
  </div>
142
310
  </div>
143
311
  </template>
@@ -67,7 +67,7 @@ addDeviceButton.addEventListener("click", () => {
67
67
  BS.Device.Connect();
68
68
  });
69
69
 
70
- const devicePair = BS.DevicePair.shared;
70
+ const devicePair = BS.DevicePair.insoles;
71
71
  devicePair.addEventListener("isConnected", () => {
72
72
  addDeviceButton.disabled = devicePair.isConnected;
73
73
  });
@@ -86,6 +86,10 @@ const toggleConnectionButtons = {};
86
86
  const togglePressureDataButtons = {};
87
87
  /** @type {Object.<string, HTMLElement[]>} */
88
88
  const pressureSensorElementsContainers = {};
89
+ /** @type {Object.<string, HTMLElement>} */
90
+ const centerOfPressureElementsContainers = {};
91
+ /** @type {Object.<string, HTMLElement>} */
92
+ const devicePairCenterOfPressureElementsContainers = {};
89
93
 
90
94
  devicePair.sides.forEach((side) => {
91
95
  /** @type {HTMLElement} */
@@ -120,24 +124,44 @@ devicePair.sides.forEach((side) => {
120
124
  /** @type {HTMLElement[]} */
121
125
  const pressureSensorElements = Array.from(insoleContainer.querySelectorAll("[data-pressure]"));
122
126
  pressureSensorElementsContainers[side] = pressureSensorElements;
127
+
128
+ centerOfPressureElementsContainers[side] = insoleContainer.querySelector(".center");
129
+ devicePairCenterOfPressureElementsContainers[side] = insoleContainer.querySelector(".devicePairCenter");
123
130
  });
124
131
 
125
132
  devicePair.addEventListener("deviceIsConnected", (event) => {
126
133
  const { device } = event.message;
127
134
 
128
- const toggleConnectionButton = toggleConnectionButtons[device.insoleSide];
135
+ const toggleConnectionButton = toggleConnectionButtons[device.side];
129
136
  if (device.isConnected) {
130
137
  toggleConnectionButton.disabled = false;
131
138
  }
132
139
  toggleConnectionButton.innerText = device.isConnected ? "disconnect" : "reconnect";
133
140
 
134
- togglePressureDataButtons[device.insoleSide].disabled = !device.isConnected;
141
+ togglePressureDataButtons[device.side].disabled = !device.isConnected;
142
+ });
143
+
144
+ devicePair.addEventListener("deviceIsConnected", (event) => {
145
+ const { device, side, isConnected } = event.message;
146
+
147
+ if (!isConnected) {
148
+ return;
149
+ }
150
+
151
+ const insoleContainer = insoleContainers[side];
152
+ const viz = insoleContainer.querySelector(".viz");
153
+ if (device.isUkaton) {
154
+ viz.classList.add("ukaton");
155
+ } else {
156
+ viz.classList.remove("ukaton");
157
+ }
158
+ console.log("insoleContainer", insoleContainer);
135
159
  });
136
160
 
137
161
  devicePair.addEventListener("deviceConnectionStatus", (event) => {
138
162
  const { device } = event.message;
139
163
 
140
- const toggleConnectionButton = toggleConnectionButtons[device.insoleSide];
164
+ const toggleConnectionButton = toggleConnectionButtons[device.side];
141
165
 
142
166
  switch (device.connectionStatus) {
143
167
  case "connected":
@@ -156,7 +180,7 @@ devicePair.addEventListener("deviceConnectionStatus", (event) => {
156
180
  devicePair.addEventListener("deviceGetSensorConfiguration", (event) => {
157
181
  const { device } = event.message;
158
182
 
159
- const togglePressureDataButton = togglePressureDataButtons[device.insoleSide];
183
+ const togglePressureDataButton = togglePressureDataButtons[device.side];
160
184
  const isPressureDataEnabled = device.sensorConfiguration.pressure > 0;
161
185
  if (isPressureDataEnabled) {
162
186
  togglePressureDataButton.innerText = "disable pressure data";
@@ -169,8 +193,85 @@ devicePair.addEventListener("deviceGetSensorConfiguration", (event) => {
169
193
  devicePair.addEventListener("devicePressure", (event) => {
170
194
  const { pressure, side } = event.message;
171
195
 
172
- pressure.sensors.forEach((sensor, index) => {
173
- pressureSensorElementsContainers[side][index].style.opacity = sensor.normalizedValue;
196
+ if (pressureVisualizationMode != "devicePairWeightedValue") {
197
+ pressure.sensors.forEach((sensor, index) => {
198
+ var value = 0;
199
+ switch (pressureVisualizationMode) {
200
+ case "normalizedValue":
201
+ value = sensor.normalizedValue;
202
+ break;
203
+ case "scaledValue":
204
+ value = sensor.scaledValue * pressure.sensors.length;
205
+ break;
206
+ case "weightedValue":
207
+ value = (sensor.weightedValue * pressure.sensors.length) / 2;
208
+ break;
209
+ }
210
+ pressureSensorElementsContainers[side][index].style.opacity = value;
211
+ });
212
+ }
213
+ });
214
+
215
+ devicePair.addEventListener("devicePressure", (event) => {
216
+ const { pressure, side } = event.message;
217
+
218
+ const container = centerOfPressureElementsContainers[side];
219
+ container.style.opacity = pressure.normalizedSum;
220
+
221
+ var center;
222
+ switch (centerOfPressureVisualizationMode) {
223
+ case "center":
224
+ center = pressure.center;
225
+ break;
226
+ case "normalizedCenter":
227
+ center = pressure.normalizedCenter;
228
+ break;
229
+ }
230
+ if (!center) {
231
+ return;
232
+ }
233
+
234
+ container.style.left = `${center.x * 100}%`;
235
+ container.style.bottom = `${center.y * 100}%`;
236
+ });
237
+
238
+ devicePair.addEventListener("pressure", (event) => {
239
+ const { pressure } = event.message;
240
+ if (pressureVisualizationMode == "devicePairWeightedValue") {
241
+ devicePair.sides.forEach((side) => {
242
+ pressure.sensors[side].forEach((sensor, index) => {
243
+ pressureSensorElementsContainers[side][index].style.opacity = sensor.weightedValue / 2;
244
+ });
245
+ });
246
+ }
247
+ });
248
+
249
+ devicePair.addEventListener("pressure", (event) => {
250
+ const { pressure } = event.message;
251
+
252
+ var center;
253
+ switch (centerOfPressureVisualizationMode) {
254
+ case "center":
255
+ center = pressure.center;
256
+ break;
257
+ case "normalizedCenter":
258
+ center = pressure.normalizedCenter;
259
+ break;
260
+ }
261
+ var side;
262
+ if (center) {
263
+ side = center.x < 0.5 ? "left" : "right";
264
+ }
265
+
266
+ devicePair.sides.forEach((_side) => {
267
+ const container = devicePairCenterOfPressureElementsContainers[_side];
268
+ if (side == _side) {
269
+ container.style.opacity = pressure.normalizedSum;
270
+ container.style.left = `${(center.x % 0.5) * 2 * 100}%`;
271
+ container.style.bottom = `${center.y * 100}%`;
272
+ } else {
273
+ container.style.opacity = 0;
274
+ }
174
275
  });
175
276
  });
176
277
 
@@ -199,3 +300,39 @@ websocketClient.addEventListener("connectionStatus", () => {
199
300
  }
200
301
  toggleServerConnectionButton.disabled = disabled;
201
302
  });
303
+
304
+ // PRESSURE VISUALIZATION
305
+
306
+ const pressureVisualizationModes = ["scaledValue", "normalizedValue", "weightedValue", "devicePairWeightedValue"];
307
+ let pressureVisualizationMode = "normalizedValue";
308
+
309
+ /** @type {HTMLSelectElement} */
310
+ const visualizationModeSelect = document.getElementById("pressureVisualizationMode");
311
+ visualizationModeSelect.addEventListener("input", (event) => {
312
+ pressureVisualizationMode = event.target.value;
313
+ console.log({ pressureVisualizationMode });
314
+ });
315
+ /** @type {HTMLOptGroupElement} */
316
+ const visualizationModeOptGroup = visualizationModeSelect.querySelector("optgroup");
317
+ pressureVisualizationModes.forEach((pressureVisualizationMode) => {
318
+ visualizationModeOptGroup.appendChild(new Option(pressureVisualizationMode));
319
+ });
320
+ visualizationModeSelect.value = pressureVisualizationMode;
321
+
322
+ // CENTER OF PRESSURE VISUALIZATION
323
+
324
+ const centerOfPressureVisualizationModes = ["normalizedCenter", "center"];
325
+ let centerOfPressureVisualizationMode = "normalizedCenter";
326
+
327
+ /** @type {HTMLSelectElement} */
328
+ const centerOfPressureVisualizationModeSelect = document.getElementById("centerOfPressureVisualizationMode");
329
+ centerOfPressureVisualizationModeSelect.addEventListener("input", (event) => {
330
+ centerOfPressureVisualizationMode = event.target.value;
331
+ console.log({ centerOfPressureVisualizationMode });
332
+ });
333
+ /** @type {HTMLOptGroupElement} */
334
+ const centerOfPressureVisualizationModeOptGroup = centerOfPressureVisualizationModeSelect.querySelector("optgroup");
335
+ centerOfPressureVisualizationModes.forEach((centerOfPressureVisualizationMode) => {
336
+ centerOfPressureVisualizationModeOptGroup.appendChild(new Option(centerOfPressureVisualizationMode));
337
+ });
338
+ centerOfPressureVisualizationModeSelect.value = centerOfPressureVisualizationMode;