brilliantsole 0.0.28 → 0.0.30

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 (136) hide show
  1. package/build/brilliantsole.cjs +6078 -444
  2. package/build/brilliantsole.cjs.map +1 -1
  3. package/build/brilliantsole.js +21734 -3031
  4. package/build/brilliantsole.js.map +1 -1
  5. package/build/brilliantsole.ls.js +23228 -5817
  6. package/build/brilliantsole.ls.js.map +1 -1
  7. package/build/brilliantsole.min.js +1 -1
  8. package/build/brilliantsole.min.js.map +1 -1
  9. package/build/brilliantsole.module.d.ts +1216 -72
  10. package/build/brilliantsole.module.js +21697 -3032
  11. package/build/brilliantsole.module.js.map +1 -1
  12. package/build/brilliantsole.module.min.d.ts +1216 -72
  13. package/build/brilliantsole.module.min.js +1 -1
  14. package/build/brilliantsole.module.min.js.map +1 -1
  15. package/build/brilliantsole.node.module.d.ts +927 -68
  16. package/build/brilliantsole.node.module.js +6053 -445
  17. package/build/brilliantsole.node.module.js.map +1 -1
  18. package/build/dts/BS.d.ts +21 -1
  19. package/build/dts/Device.d.ts +152 -12
  20. package/build/dts/DeviceManager.d.ts +3 -3
  21. package/build/dts/DisplayManager.d.ts +320 -0
  22. package/build/dts/FileTransferManager.d.ts +10 -4
  23. package/build/dts/MicrophoneManager.d.ts +88 -0
  24. package/build/dts/connection/BaseConnectionManager.d.ts +2 -2
  25. package/build/dts/connection/bluetooth/BluetoothUUID.d.ts +12 -0
  26. package/build/dts/devicePair/DevicePair.d.ts +5 -5
  27. package/build/dts/sensor/SensorConfigurationManager.d.ts +2 -1
  28. package/build/dts/sensor/SensorDataManager.d.ts +3 -3
  29. package/build/dts/server/BaseClient.d.ts +4 -4
  30. package/build/dts/server/udp/UDPUtils.d.ts +1 -1
  31. package/build/dts/utils/ArrayBufferUtils.d.ts +1 -0
  32. package/build/dts/utils/AudioUtils.d.ts +2 -0
  33. package/build/dts/utils/BitmapUtils.d.ts +17 -0
  34. package/build/dts/utils/ColorUtils.d.ts +5 -0
  35. package/build/dts/utils/DisplayBitmapUtils.d.ts +47 -0
  36. package/build/dts/utils/DisplayCanvasHelper.d.ts +270 -0
  37. package/build/dts/utils/DisplayContextCommand.d.ts +300 -0
  38. package/build/dts/utils/DisplayContextState.d.ts +51 -0
  39. package/build/dts/utils/DisplayContextStateHelper.d.ts +9 -0
  40. package/build/dts/utils/DisplayManagerInterface.d.ts +173 -0
  41. package/build/dts/utils/DisplaySpriteSheetUtils.d.ts +72 -0
  42. package/build/dts/utils/DisplayUtils.d.ts +70 -0
  43. package/build/dts/utils/MathUtils.d.ts +16 -0
  44. package/build/dts/utils/PathUtils.d.ts +4 -0
  45. package/build/dts/utils/RangeHelper.d.ts +7 -0
  46. package/build/dts/utils/SpriteSheetUtils.d.ts +20 -0
  47. package/build/index.d.ts +1216 -72
  48. package/build/index.node.d.ts +927 -68
  49. package/examples/3d-generic/index.html +5 -0
  50. package/examples/3d-generic/script.js +1 -0
  51. package/examples/basic/index.html +443 -53
  52. package/examples/basic/script.js +1551 -24
  53. package/examples/camera/barcode-detector.js +109 -0
  54. package/examples/camera/depth-estimation.js +71 -0
  55. package/examples/camera/face-detector.js +119 -0
  56. package/examples/camera/face-landmark.js +111 -0
  57. package/examples/camera/gesture-recognition.js +97 -0
  58. package/examples/camera/hand-landmark.js +74 -0
  59. package/examples/camera/image-segmentation.js +98 -0
  60. package/examples/camera/image-to-text.js +43 -0
  61. package/examples/camera/image-upscale.js +75 -0
  62. package/examples/camera/index.html +129 -0
  63. package/examples/camera/object-detection.js +98 -0
  64. package/examples/camera/pose-landmark.js +60 -0
  65. package/examples/camera/script.js +316 -0
  66. package/examples/camera/utils.js +165 -0
  67. package/examples/camera/yolo-tiny.js +54 -0
  68. package/examples/camera/yolo.js +119 -0
  69. package/examples/display-3d/index.html +195 -0
  70. package/examples/display-3d/script.js +1235 -0
  71. package/examples/display-canvas/aframe.js +42950 -0
  72. package/examples/display-canvas/index.html +245 -0
  73. package/examples/display-canvas/script.js +2312 -0
  74. package/examples/display-image/index.html +189 -0
  75. package/examples/display-image/script.js +1093 -0
  76. package/examples/display-spritesheet/index.html +960 -0
  77. package/examples/display-spritesheet/script.js +4243 -0
  78. package/examples/display-text/index.html +195 -0
  79. package/examples/display-text/script.js +1418 -0
  80. package/examples/display-wireframe/index.html +204 -0
  81. package/examples/display-wireframe/script.js +1167 -0
  82. package/examples/edge-impulse/script.js +23 -5
  83. package/examples/glasses-gestures/README.md +11 -0
  84. package/examples/glasses-gestures/edge-impulse-standalone.js +7228 -0
  85. package/examples/glasses-gestures/edge-impulse-standalone.wasm +0 -0
  86. package/examples/glasses-gestures/index.html +74 -0
  87. package/examples/glasses-gestures/run-impulse.js +135 -0
  88. package/examples/glasses-gestures/script.js +228 -0
  89. package/examples/microphone/index.html +104 -0
  90. package/examples/microphone/script.js +394 -0
  91. package/examples/microphone/utils.js +45 -0
  92. package/examples/microphone/whisper-realtime.js +166 -0
  93. package/examples/microphone/whisper.js +132 -0
  94. package/examples/punch/index.html +4 -1
  95. package/examples/server/script.js +0 -1
  96. package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
  97. package/examples/webxr-3/components/bs-camera.js +65 -0
  98. package/examples/webxr-3/index.html +134 -0
  99. package/examples/webxr-3/script.js +432 -0
  100. package/package.json +10 -2
  101. package/src/BS.ts +101 -1
  102. package/src/CameraManager.ts +10 -8
  103. package/src/Device.ts +652 -11
  104. package/src/DisplayManager.ts +2989 -0
  105. package/src/FileTransferManager.ts +79 -26
  106. package/src/InformationManager.ts +8 -7
  107. package/src/MicrophoneManager.ts +606 -0
  108. package/src/TfliteManager.ts +4 -2
  109. package/src/WifiManager.ts +4 -1
  110. package/src/connection/BaseConnectionManager.ts +4 -0
  111. package/src/connection/bluetooth/bluetoothUUIDs.ts +36 -1
  112. package/src/devicePair/DevicePairPressureSensorDataManager.ts +1 -1
  113. package/src/scanner/NobleScanner.ts +1 -1
  114. package/src/sensor/SensorConfigurationManager.ts +16 -8
  115. package/src/sensor/SensorDataManager.ts +5 -0
  116. package/src/server/udp/UDPServer.ts +4 -4
  117. package/src/server/udp/UDPUtils.ts +1 -1
  118. package/src/server/websocket/WebSocketClient.ts +50 -1
  119. package/src/utils/ArrayBufferUtils.ts +23 -5
  120. package/src/utils/AudioUtils.ts +65 -0
  121. package/src/utils/ColorUtils.ts +66 -0
  122. package/src/utils/DisplayBitmapUtils.ts +695 -0
  123. package/src/utils/DisplayCanvasHelper.ts +4222 -0
  124. package/src/utils/DisplayContextCommand.ts +1566 -0
  125. package/src/utils/DisplayContextState.ts +138 -0
  126. package/src/utils/DisplayContextStateHelper.ts +48 -0
  127. package/src/utils/DisplayManagerInterface.ts +1356 -0
  128. package/src/utils/DisplaySpriteSheetUtils.ts +782 -0
  129. package/src/utils/DisplayUtils.ts +529 -0
  130. package/src/utils/EventDispatcher.ts +59 -14
  131. package/src/utils/MathUtils.ts +88 -2
  132. package/src/utils/ObjectUtils.ts +6 -1
  133. package/src/utils/PathUtils.ts +192 -0
  134. package/src/utils/RangeHelper.ts +15 -3
  135. package/src/utils/Timer.ts +1 -1
  136. package/src/utils/environment.ts +15 -6
@@ -1419,7 +1419,7 @@ const updateConnectViaWebSocketsButton = () => {
1419
1419
  device.isConnected &&
1420
1420
  device.connectionType == "webBluetooth" &&
1421
1421
  device.isWifiConnected;
1422
- console.log({ enabled });
1422
+ // console.log({ enabled });
1423
1423
  connectViaWebSocketsButton.disabled = !enabled;
1424
1424
  };
1425
1425
  device.addEventListener("isWifiConnected", () =>
@@ -1460,7 +1460,7 @@ device.addEventListener("getSensorConfiguration", () => {
1460
1460
  const updateTakePictureButton = () => {
1461
1461
  takePictureButton.disabled =
1462
1462
  !device.isConnected ||
1463
- device.sensorConfiguration.camera == 0 ||
1463
+ //device.sensorConfiguration.camera == 0 ||
1464
1464
  device.cameraStatus != "idle";
1465
1465
  };
1466
1466
  device.addEventListener("cameraStatus", () => {
@@ -1485,7 +1485,7 @@ device.addEventListener("getSensorConfiguration", () => {
1485
1485
  const updateFocusCameraButton = () => {
1486
1486
  focusCameraButton.disabled =
1487
1487
  !device.isConnected ||
1488
- device.sensorConfiguration.camera == 0 ||
1488
+ //device.sensorConfiguration.camera == 0 ||
1489
1489
  device.cameraStatus != "idle";
1490
1490
  };
1491
1491
  device.addEventListener("cameraStatus", (event) => {
@@ -1654,27 +1654,6 @@ takePictureAfterUpdateCheckbox.addEventListener("input", () => {
1654
1654
  console.log({ takePictureAfterUpdate });
1655
1655
  });
1656
1656
 
1657
- let barcodeDetector;
1658
- BarcodeDetector.getSupportedFormats().then((supportedFormats) => {
1659
- console.log({ supportedFormats });
1660
- // create new detector
1661
- barcodeDetector = new BarcodeDetector({
1662
- formats: supportedFormats,
1663
- });
1664
- });
1665
- cameraImage.addEventListener("load", () => {
1666
- if (barcodeDetector) {
1667
- barcodeDetector
1668
- .detect(cameraImage)
1669
- .then((barcodes) => {
1670
- barcodes.forEach((barcode) => console.log(barcode.rawValue));
1671
- })
1672
- .catch((err) => {
1673
- console.log(err);
1674
- });
1675
- }
1676
- });
1677
-
1678
1657
  /** @type {HTMLInputElement} */
1679
1658
  const cameraWhiteBalanceInput = document.getElementById("cameraWhiteBalance");
1680
1659
  const updateWhiteBalance = BS.ThrottleUtils.throttle(
@@ -1731,3 +1710,1551 @@ device.addEventListener("connected", () => {
1731
1710
  device.addEventListener("getCameraConfiguration", () => {
1732
1711
  updateCameraWhiteBalanceInput();
1733
1712
  });
1713
+
1714
+ // MICROPHONE
1715
+
1716
+ /** @type {HTMLSpanElement} */
1717
+ const isMicrophoneAvailableSpan = document.getElementById(
1718
+ "isMicrophoneAvailable"
1719
+ );
1720
+ device.addEventListener("connected", () => {
1721
+ isMicrophoneAvailableSpan.innerText = device.hasMicrophone;
1722
+ });
1723
+
1724
+ /** @type {HTMLSpanElement} */
1725
+ const microphoneStatusSpan = document.getElementById("microphoneStatus");
1726
+ device.addEventListener("microphoneStatus", () => {
1727
+ microphoneStatusSpan.innerText = device.microphoneStatus;
1728
+ });
1729
+
1730
+ /** @type {HTMLPreElement} */
1731
+ const microphoneConfigurationPre = document.getElementById(
1732
+ "microphoneConfigurationPre"
1733
+ );
1734
+ device.addEventListener("getMicrophoneConfiguration", () => {
1735
+ microphoneConfigurationPre.textContent = JSON.stringify(
1736
+ device.microphoneConfiguration,
1737
+ null,
1738
+ 2
1739
+ );
1740
+ });
1741
+
1742
+ const microphoneConfigurationContainer = document.getElementById(
1743
+ "microphoneConfiguration"
1744
+ );
1745
+ /** @type {HTMLTemplateElement} */
1746
+ const microphoneConfigurationTypeTemplate = document.getElementById(
1747
+ "microphoneConfigurationTypeTemplate"
1748
+ );
1749
+ BS.MicrophoneConfigurationTypes.forEach((microphoneConfigurationType) => {
1750
+ const microphoneConfigurationTypeContainer =
1751
+ microphoneConfigurationTypeTemplate.content
1752
+ .cloneNode(true)
1753
+ .querySelector(".microphoneConfigurationType");
1754
+
1755
+ microphoneConfigurationContainer.appendChild(
1756
+ microphoneConfigurationTypeContainer
1757
+ );
1758
+
1759
+ microphoneConfigurationTypeContainer.querySelector(".type").innerText =
1760
+ microphoneConfigurationType;
1761
+
1762
+ /** @type {HTMLSelectElement} */
1763
+ const select = microphoneConfigurationTypeContainer.querySelector("select");
1764
+ /** @type {HTMLOptGroupElement} */
1765
+ const optgroup = select.querySelector("optgroup");
1766
+ optgroup.label = microphoneConfigurationType;
1767
+
1768
+ BS.MicrophoneConfigurationValues[microphoneConfigurationType].forEach(
1769
+ (value) => {
1770
+ optgroup.appendChild(new Option(value));
1771
+ }
1772
+ );
1773
+
1774
+ /** @type {HTMLSpanElement} */
1775
+ const span = microphoneConfigurationTypeContainer.querySelector("span");
1776
+
1777
+ device.addEventListener("isConnected", () => {
1778
+ updateisInputDisabled();
1779
+ });
1780
+ device.addEventListener("microphoneStatus", () => {
1781
+ updateisInputDisabled();
1782
+ });
1783
+ const updateisInputDisabled = () => {
1784
+ select.disabled =
1785
+ !device.isConnected ||
1786
+ !device.hasMicrophone ||
1787
+ device.microphoneStatus != "idle";
1788
+ };
1789
+
1790
+ const updateSelect = () => {
1791
+ const value = device.microphoneConfiguration[microphoneConfigurationType];
1792
+ span.innerText = value;
1793
+ select.value = value;
1794
+ };
1795
+
1796
+ device.addEventListener("connected", () => {
1797
+ if (!device.hasMicrophone) {
1798
+ return;
1799
+ }
1800
+ updateSelect();
1801
+ });
1802
+
1803
+ device.addEventListener("getMicrophoneConfiguration", () => {
1804
+ updateSelect();
1805
+ });
1806
+
1807
+ select.addEventListener("input", () => {
1808
+ const value = select.value;
1809
+ // console.log(`updating ${microphoneConfigurationType} to ${value}`);
1810
+ device.setMicrophoneConfiguration({
1811
+ [microphoneConfigurationType]: value,
1812
+ });
1813
+ });
1814
+ });
1815
+
1816
+ /** @type {HTMLButtonElement} */
1817
+ const toggleMicrophoneButton = document.getElementById("toggleMicrophone");
1818
+ toggleMicrophoneButton.addEventListener("click", () => {
1819
+ device.toggleMicrophone();
1820
+ });
1821
+ device.addEventListener("connected", () => {
1822
+ updateToggleMicrophoneButton();
1823
+ });
1824
+ device.addEventListener("getSensorConfiguration", () => {
1825
+ updateToggleMicrophoneButton();
1826
+ });
1827
+ const updateToggleMicrophoneButton = () => {
1828
+ let disabled =
1829
+ !device.isConnected ||
1830
+ device.sensorConfiguration.microphone == 0 ||
1831
+ !device.hasMicrophone;
1832
+
1833
+ switch (device.microphoneStatus) {
1834
+ case "streaming":
1835
+ toggleMicrophoneButton.innerText = "stop microphone";
1836
+ break;
1837
+ case "idle":
1838
+ toggleMicrophoneButton.innerText = "start microphone";
1839
+ break;
1840
+ }
1841
+ toggleMicrophoneButton.disabled = disabled;
1842
+ };
1843
+ device.addEventListener("microphoneStatus", () => {
1844
+ updateToggleMicrophoneButton();
1845
+ });
1846
+
1847
+ /** @type {HTMLButtonElement} */
1848
+ const startMicrophoneButton = document.getElementById("startMicrophone");
1849
+ startMicrophoneButton.addEventListener("click", () => {
1850
+ device.startMicrophone();
1851
+ });
1852
+ /** @type {HTMLButtonElement} */
1853
+ const stopMicrophoneButton = document.getElementById("stopMicrophone");
1854
+ stopMicrophoneButton.addEventListener("click", () => {
1855
+ device.stopMicrophone();
1856
+ });
1857
+ /** @type {HTMLButtonElement} */
1858
+ const enableMicrophoneVadButton = document.getElementById("enableMicrphoneVad");
1859
+ enableMicrophoneVadButton.addEventListener("click", () => {
1860
+ device.enableMicrophoneVad();
1861
+ });
1862
+
1863
+ const updateMicrophoneButtons = () => {
1864
+ let disabled =
1865
+ !device.isConnected ||
1866
+ device.sensorConfiguration.microphone == 0 ||
1867
+ !device.hasMicrophone;
1868
+
1869
+ startMicrophoneButton.disabled =
1870
+ disabled || device.microphoneStatus == "streaming";
1871
+ stopMicrophoneButton.disabled = disabled || device.microphoneStatus == "idle";
1872
+ enableMicrophoneVadButton.disabled =
1873
+ disabled || device.microphoneStatus == "vad";
1874
+ };
1875
+ device.addEventListener("microphoneStatus", () => {
1876
+ updateMicrophoneButtons();
1877
+ });
1878
+ device.addEventListener("connected", () => {
1879
+ updateMicrophoneButtons();
1880
+ });
1881
+ device.addEventListener("getSensorConfiguration", () => {
1882
+ updateMicrophoneButtons();
1883
+ });
1884
+
1885
+ const audioContext = new (window.AudioContext || window.webkitAudioContext)();
1886
+ const checkAudioContextState = () => {
1887
+ const { state } = audioContext;
1888
+ console.log({ audioContextState: state });
1889
+ if (state != "running") {
1890
+ document.addEventListener("click", () => audioContext.resume(), {
1891
+ once: true,
1892
+ });
1893
+ }
1894
+ };
1895
+ audioContext.addEventListener("statechange", () => {
1896
+ checkAudioContextState();
1897
+ });
1898
+ checkAudioContextState();
1899
+
1900
+ device.audioContext = audioContext;
1901
+
1902
+ /** @type {HTMLAudioElement} */
1903
+ const microphoneStreamAudioElement =
1904
+ document.getElementById("microphoneStream");
1905
+ microphoneStreamAudioElement.srcObject =
1906
+ device.microphoneMediaStreamDestination.stream;
1907
+
1908
+ /** @type {HTMLAudioElement} */
1909
+ const microphoneRecordingAudioElement = document.getElementById(
1910
+ "microphoneRecording"
1911
+ );
1912
+ /** @type {HTMLInputElement} */
1913
+ const autoPlayMicrphoneRecordingCheckbox = document.getElementById(
1914
+ "autoPlayMicrphoneRecording"
1915
+ );
1916
+ let autoPlayMicrphoneRecording = autoPlayMicrphoneRecordingCheckbox.checked;
1917
+ console.log("autoPlayMicrphoneRecording", autoPlayMicrphoneRecording);
1918
+ autoPlayMicrphoneRecordingCheckbox.addEventListener("input", () => {
1919
+ autoPlayMicrphoneRecording = autoPlayMicrphoneRecordingCheckbox.checked;
1920
+ console.log({ autoPlayMicrphoneRecording });
1921
+ });
1922
+ device.addEventListener("microphoneRecording", (event) => {
1923
+ microphoneRecordingAudioElement.src = event.message.url;
1924
+ if (autoPlayMicrphoneRecording) {
1925
+ microphoneRecordingAudioElement.play();
1926
+ }
1927
+ });
1928
+
1929
+ /** @type {HTMLButtonElement} */
1930
+ const toggleMicrophoneRecordingButton = document.getElementById(
1931
+ "toggleMicrophoneRecording"
1932
+ );
1933
+ toggleMicrophoneRecordingButton.addEventListener("click", () => {
1934
+ device.toggleMicrophoneRecording();
1935
+ });
1936
+ device.addEventListener("connected", () => {
1937
+ updateToggleMicrophoneRecordingButton();
1938
+ });
1939
+ device.addEventListener("getSensorConfiguration", () => {
1940
+ updateToggleMicrophoneRecordingButton();
1941
+ });
1942
+ const updateToggleMicrophoneRecordingButton = () => {
1943
+ let disabled =
1944
+ !device.isConnected ||
1945
+ device.sensorConfiguration.microphone == 0 ||
1946
+ !device.hasMicrophone ||
1947
+ device.microphoneStatus != "streaming";
1948
+
1949
+ toggleMicrophoneRecordingButton.innerText = device.isRecordingMicrophone
1950
+ ? "stop recording"
1951
+ : "start recording";
1952
+
1953
+ toggleMicrophoneRecordingButton.disabled = disabled;
1954
+ };
1955
+ device.addEventListener("isRecordingMicrophone", () => {
1956
+ updateToggleMicrophoneRecordingButton();
1957
+ });
1958
+ device.addEventListener("microphoneStatus", () => {
1959
+ updateToggleMicrophoneRecordingButton();
1960
+ });
1961
+
1962
+ // DISPLAY
1963
+
1964
+ /** @type {HTMLSpanElement} */
1965
+ const isDisplayAvailableSpan = document.getElementById("isDisplayAvailable");
1966
+ device.addEventListener("connected", () => {
1967
+ isDisplayAvailableSpan.innerText = device.isDisplayAvailable;
1968
+ });
1969
+
1970
+ /** @type {HTMLSpanElement} */
1971
+ const displayStatusSpan = document.getElementById("displayStatus");
1972
+ device.addEventListener("displayStatus", () => {
1973
+ if (!device.isDisplayAvailable) {
1974
+ return;
1975
+ }
1976
+ displayStatusSpan.innerText = device.displayStatus;
1977
+ });
1978
+
1979
+ /** @type {HTMLButtonElement} */
1980
+ const toggleDisplayButton = document.getElementById("toggleDisplay");
1981
+ toggleDisplayButton.addEventListener("click", () => {
1982
+ device.toggleDisplay();
1983
+ });
1984
+ device.addEventListener("connected", () => {
1985
+ updateToggleDisplayButton();
1986
+ });
1987
+ device.addEventListener("displayStatus", () => {
1988
+ updateToggleDisplayButton();
1989
+ });
1990
+ const updateToggleDisplayButton = () => {
1991
+ if (!device.isDisplayAvailable) {
1992
+ return;
1993
+ }
1994
+ let disabled = !device.isConnected || !device.isDisplayAvailable;
1995
+ switch (device.displayStatus) {
1996
+ case "asleep":
1997
+ toggleDisplayButton.innerText = "enable display";
1998
+ break;
1999
+ case "awake":
2000
+ toggleDisplayButton.innerText = "disable display";
2001
+ break;
2002
+ default:
2003
+ disabled = true;
2004
+ break;
2005
+ }
2006
+ toggleDisplayButton.disabled = disabled;
2007
+ };
2008
+
2009
+ /** @type {HTMLPreElement} */
2010
+ const displayInformationPre = document.getElementById("displayInformationPre");
2011
+ device.addEventListener("displayInformation", () => {
2012
+ displayInformationPre.textContent = JSON.stringify(
2013
+ device.displayInformation,
2014
+ null,
2015
+ 2
2016
+ );
2017
+ });
2018
+
2019
+ /** @type {HTMLSelectElement} */
2020
+ const setDisplayBrightnessSelect = document.getElementById(
2021
+ "setDisplayBrightnessSelect"
2022
+ );
2023
+ /** @type {HTMLOptGroupElement} */
2024
+ const setDisplayBrightnessSelectOptgroup =
2025
+ setDisplayBrightnessSelect.querySelector("optgroup");
2026
+ BS.DisplayBrightnesses.forEach((displayBrightness) => {
2027
+ setDisplayBrightnessSelectOptgroup.appendChild(new Option(displayBrightness));
2028
+ });
2029
+
2030
+ device.addEventListener("isConnected", () => {
2031
+ setDisplayBrightnessSelect.disabled = !device.isConnected;
2032
+ });
2033
+
2034
+ device.addEventListener("getDisplayBrightness", () => {
2035
+ setDisplayBrightnessSelect.value = device.displayBrightness;
2036
+ });
2037
+
2038
+ setDisplayBrightnessSelect.addEventListener("input", () => {
2039
+ device.setDisplayBrightness(setDisplayBrightnessSelect.value);
2040
+ });
2041
+
2042
+ /** @type {HTMLTemplateElement} */
2043
+ const displayColorTemplate = document.getElementById("displayColorTemplate");
2044
+ const displayColorsContainer = document.getElementById("displayColors");
2045
+ /** @type {string[]} */
2046
+ const setDisplayColor = BS.ThrottleUtils.throttle(
2047
+ (colorIndex, colorString) => {
2048
+ // console.log({ colorIndex, colorString });
2049
+ device.setDisplayColor(colorIndex, colorString, true);
2050
+ updateBitmapCanvas();
2051
+ },
2052
+ 100,
2053
+ true
2054
+ );
2055
+ device.addEventListener("notConnected", () => {
2056
+ displayColorsContainer.innerHTML = "";
2057
+ });
2058
+ device.addEventListener("connected", () => {
2059
+ displayColorsContainer.innerHTML = "";
2060
+ if (device.isDisplayAvailable) {
2061
+ for (
2062
+ let colorIndex = 0;
2063
+ colorIndex < device.numberOfDisplayColors;
2064
+ colorIndex++
2065
+ ) {
2066
+ const displayColorContainer = displayColorTemplate.content
2067
+ .cloneNode(true)
2068
+ .querySelector(".displayColor");
2069
+
2070
+ const displayColorIndex =
2071
+ displayColorContainer.querySelector(".colorIndex");
2072
+ displayColorIndex.innerText = `color #${colorIndex}`;
2073
+ const displayColorInput = displayColorContainer.querySelector("input");
2074
+ displayColorInput.addEventListener("input", () => {
2075
+ setDisplayColor(colorIndex, displayColorInput.value);
2076
+ if (colorIndex == fillColorIndex) {
2077
+ fillColorInput.value = displayColorInput.value;
2078
+ }
2079
+ if (colorIndex == lineColorIndex) {
2080
+ lineColorInput.value = displayColorInput.value;
2081
+ }
2082
+
2083
+ const bitmapColorIndexContainers = Array.from(
2084
+ bitmapColorIndicesContainer.querySelectorAll(".bitmapColorIndex")
2085
+ );
2086
+
2087
+ bitmapColorIndexContainers.forEach(
2088
+ (bitmapColorIndexContainer, bitmapColorIndex) => {
2089
+ if (
2090
+ bitmapColorIndexContainer.querySelector("select").value !=
2091
+ colorIndex
2092
+ ) {
2093
+ return;
2094
+ }
2095
+
2096
+ const bitmapColorIndexColorInput =
2097
+ bitmapColorIndexContainer.querySelector("input");
2098
+ bitmapColorIndexColorInput.value = displayColorInput.value;
2099
+
2100
+ const bitmapColorIndexSelect =
2101
+ bitmapColorIndexContainer.querySelector("select");
2102
+ bitmapColorIndexSelect.value = colorIndex;
2103
+
2104
+ if (bitmapColorIndex == currentBitmapColorIndex) {
2105
+ currentBitmapColorIndexColorInput.value = displayColorInput.value;
2106
+ }
2107
+ }
2108
+ );
2109
+ });
2110
+ displayColorsContainer.appendChild(displayColorContainer);
2111
+ }
2112
+ }
2113
+ });
2114
+ device.addEventListener("displayColor", (event) => {
2115
+ const { colorIndex, colorRGB, colorHex } = event.message;
2116
+ displayColorsContainer
2117
+ .querySelectorAll(".displayColor")
2118
+ [colorIndex].querySelector("input").value = colorHex;
2119
+ });
2120
+
2121
+ /** @type {HTMLTemplateElement} */
2122
+ const displayColorOpacityTemplate = document.getElementById(
2123
+ "displayColorOpacityTemplate"
2124
+ );
2125
+ const displayColorOpacitiesContainer = document.getElementById(
2126
+ "displayColorOpacities"
2127
+ );
2128
+ const setDisplayColorOpacity = BS.ThrottleUtils.throttle(
2129
+ (colorIndex, opacity) => {
2130
+ console.log({ colorIndex, opacity });
2131
+ device.setDisplayColorOpacity(colorIndex, opacity, true);
2132
+ },
2133
+ 100,
2134
+ true
2135
+ );
2136
+ device.addEventListener("notConnected", () => {
2137
+ displayColorOpacitiesContainer.innerHTML = "";
2138
+ });
2139
+ device.addEventListener("connected", () => {
2140
+ displayColorOpacitiesContainer.innerHTML = "";
2141
+ if (device.isDisplayAvailable) {
2142
+ for (
2143
+ let colorIndex = 0;
2144
+ colorIndex < device.numberOfDisplayColors;
2145
+ colorIndex++
2146
+ ) {
2147
+ const displayColorOpacityContainer = displayColorOpacityTemplate.content
2148
+ .cloneNode(true)
2149
+ .querySelector(".displayColorOpacity");
2150
+
2151
+ const displayColorOpacityIndex =
2152
+ displayColorOpacityContainer.querySelector(".colorIndex");
2153
+ displayColorOpacityIndex.innerText = `opacity #${colorIndex}`;
2154
+ const displayColorOpacityInput =
2155
+ displayColorOpacityContainer.querySelector("input");
2156
+ const displayColorOpacitySpan =
2157
+ displayColorOpacityContainer.querySelector("span");
2158
+ displayColorOpacityInput.addEventListener("input", () => {
2159
+ const opacity = Number(displayColorOpacityInput.value);
2160
+ displayColorOpacitySpan.innerText = Math.round(opacity * 100);
2161
+ setDisplayColorOpacity(colorIndex, opacity);
2162
+ });
2163
+ displayColorOpacitiesContainer.appendChild(displayColorOpacityContainer);
2164
+ }
2165
+ }
2166
+ });
2167
+
2168
+ const displayOpacityContainer = document.getElementById("displayOpacity");
2169
+ const displayOpacitySpan = displayOpacityContainer.querySelector("span");
2170
+ const displayOpacityInput = displayOpacityContainer.querySelector("input");
2171
+
2172
+ const setDisplayOpacity = BS.ThrottleUtils.throttle(
2173
+ (opacity) => {
2174
+ console.log({ opacity });
2175
+ device.setDisplayOpacity(opacity, true);
2176
+ },
2177
+ 100,
2178
+ true
2179
+ );
2180
+ displayOpacityInput.addEventListener("input", () => {
2181
+ const opacity = Number(displayOpacityInput.value);
2182
+ displayOpacitySpan.innerText = Math.round(opacity * 100);
2183
+ setDisplayOpacity(opacity);
2184
+ displayColorOpacitiesContainer
2185
+ .querySelectorAll(".displayColorOpacity")
2186
+ .forEach((container) => {
2187
+ const input = container.querySelector("input");
2188
+ const opacitySpan = container.querySelector("span.opacity");
2189
+ input.value = opacity;
2190
+ opacitySpan.innerText = Math.round(opacity * 100);
2191
+ });
2192
+ });
2193
+
2194
+ device.addEventListener("isConnected", () => {
2195
+ const enabled = device.isConnected && device.isDisplayAvailable;
2196
+ displayOpacityInput.disabled = !enabled;
2197
+ });
2198
+
2199
+ const fillColorContainer = document.getElementById("fillColor");
2200
+ const fillColorSelect = fillColorContainer.querySelector("select");
2201
+ const fillColorOptgroup = fillColorSelect.querySelector("optgroup");
2202
+ device.addEventListener("connected", () => {
2203
+ if (!device.isDisplayAvailable) {
2204
+ return;
2205
+ }
2206
+ fillColorOptgroup.innerHTML = "";
2207
+ for (
2208
+ let colorIndex = 0;
2209
+ colorIndex < device.numberOfDisplayColors;
2210
+ colorIndex++
2211
+ ) {
2212
+ fillColorOptgroup.appendChild(new Option(colorIndex));
2213
+ }
2214
+ fillColorSelect.value = fillColorIndex;
2215
+ });
2216
+ const fillColorInput = fillColorContainer.querySelector("input");
2217
+ let fillColorIndex = 1;
2218
+ fillColorSelect.addEventListener("input", () => {
2219
+ fillColorIndex = Number(fillColorSelect.value);
2220
+ console.log({ fillColorIndex });
2221
+ device.selectDisplayFillColor(fillColorIndex);
2222
+ drawShape();
2223
+ fillColorInput.value = device.displayColors[fillColorIndex];
2224
+ });
2225
+
2226
+ device.addEventListener("isConnected", () => {
2227
+ const enabled = device.isConnected && device.isDisplayAvailable;
2228
+ fillColorSelect.disabled = !enabled;
2229
+ // console.log({ enabled });
2230
+ });
2231
+
2232
+ const lineColorContainer = document.getElementById("lineColor");
2233
+ const lineColorSelect = lineColorContainer.querySelector("select");
2234
+ const lineColorOptgroup = lineColorSelect.querySelector("optgroup");
2235
+ let lineColorIndex = 1;
2236
+ device.addEventListener("connected", () => {
2237
+ if (!device.isDisplayAvailable) {
2238
+ return;
2239
+ }
2240
+ lineColorOptgroup.innerHTML = "";
2241
+ for (
2242
+ let colorIndex = 0;
2243
+ colorIndex < device.numberOfDisplayColors;
2244
+ colorIndex++
2245
+ ) {
2246
+ lineColorOptgroup.appendChild(new Option(colorIndex));
2247
+ }
2248
+ lineColorSelect.value = lineColorIndex;
2249
+ });
2250
+ const lineColorInput = lineColorContainer.querySelector("input");
2251
+ lineColorSelect.addEventListener("input", () => {
2252
+ lineColorIndex = Number(lineColorSelect.value);
2253
+ console.log({ lineColorIndex });
2254
+ device.selectDisplayLineColor(lineColorIndex);
2255
+ drawShape();
2256
+ lineColorInput.value = device.displayColors[lineColorIndex];
2257
+ });
2258
+ device.addEventListener("isConnected", () => {
2259
+ const enabled = device.isConnected && device.isDisplayAvailable;
2260
+ lineColorSelect.disabled = !enabled;
2261
+ });
2262
+
2263
+ const backgroundColorContainer = document.getElementById("backgroundColor");
2264
+ const backgroundColorSelect = backgroundColorContainer.querySelector("select");
2265
+ const backgroundColorOptgroup = backgroundColorSelect.querySelector("optgroup");
2266
+ let backgroundColorIndex = 0;
2267
+ device.addEventListener("connected", () => {
2268
+ if (!device.isDisplayAvailable) {
2269
+ return;
2270
+ }
2271
+ backgroundColorOptgroup.innerHTML = "";
2272
+ for (
2273
+ let colorIndex = 0;
2274
+ colorIndex < device.numberOfDisplayColors;
2275
+ colorIndex++
2276
+ ) {
2277
+ backgroundColorOptgroup.appendChild(new Option(colorIndex));
2278
+ }
2279
+ backgroundColorSelect.value = backgroundColorIndex;
2280
+ });
2281
+ const backgroundColorInput = backgroundColorContainer.querySelector("input");
2282
+ backgroundColorSelect.addEventListener("input", () => {
2283
+ backgroundColorIndex = Number(backgroundColorSelect.value);
2284
+ console.log({ backgroundColorIndex });
2285
+ device.setDisplayFillBackground(backgroundColorIndex != 0);
2286
+ device.selectDisplayBackgroundColor(backgroundColorIndex);
2287
+ drawShape();
2288
+ backgroundColorInput.value = device.displayColors[backgroundColorIndex];
2289
+ });
2290
+ device.addEventListener("isConnected", () => {
2291
+ const enabled = device.isConnected && device.isDisplayAvailable;
2292
+ backgroundColorSelect.disabled = !enabled;
2293
+ });
2294
+
2295
+ let drawWhenReady = false;
2296
+ let lastDrawTime = 0;
2297
+ let lastDrawReadyTime = 0;
2298
+ let pendingParams;
2299
+ device.addEventListener("displayReady", () => {
2300
+ lastDrawReadyTime = Date.now();
2301
+ // console.log("ready", lastDrawReadyTime - lastDrawTime);
2302
+ if (drawWhenReady) {
2303
+ drawWhenReady = false;
2304
+ drawShape(pendingParams);
2305
+ }
2306
+ });
2307
+ const drawShape = (updatedParams) => {
2308
+ if (device.isConnected && device.isDisplayAvailable) {
2309
+ if (!device.isDisplayReady) {
2310
+ drawWhenReady = true;
2311
+ pendingParams = updatedParams;
2312
+ return;
2313
+ }
2314
+ lastDrawTime = Date.now();
2315
+
2316
+ if (false)
2317
+ console.log("draw", {
2318
+ drawShapeType,
2319
+ drawWidth,
2320
+ drawHeight,
2321
+ drawX,
2322
+ drawY,
2323
+ drawBorderRadius,
2324
+ drawStartAngle,
2325
+ drawAngleOffset,
2326
+ drawBitmapScaleX,
2327
+ drawBitmapScaleY,
2328
+ drawBitmapScale,
2329
+ });
2330
+ if (updatedParams?.includes("lineWidth")) {
2331
+ device.setDisplayLineWidth(lineWidth);
2332
+ }
2333
+ if (updatedParams?.includes("rotation")) {
2334
+ device.setDisplayRotation(rotation);
2335
+ }
2336
+ if (updatedParams?.includes("segmentStartCap")) {
2337
+ device.setDisplaySegmentStartCap(segmentStartCap);
2338
+ }
2339
+ if (updatedParams?.includes("segmentEndCap")) {
2340
+ device.setDisplaySegmentEndCap(segmentEndCap);
2341
+ }
2342
+ if (updatedParams?.includes("verticalAlignment")) {
2343
+ device.setDisplayVerticalAlignment(verticalAlignment);
2344
+ }
2345
+ if (updatedParams?.includes("horizontalAlignment")) {
2346
+ device.setDisplayHorizontalAlignment(horizontalAlignment);
2347
+ }
2348
+ if (updatedParams?.includes("segmentStartRadius")) {
2349
+ device.setDisplaySegmentStartRadius(drawSegmentStartRadius);
2350
+ }
2351
+ if (updatedParams?.includes("segmentEndRadius")) {
2352
+ device.setDisplaySegmentEndRadius(drawSegmentEndRadius);
2353
+ }
2354
+
2355
+ if (updatedParams?.includes("cropTop")) {
2356
+ device.setDisplayCropTop(drawCropTop);
2357
+ }
2358
+ if (updatedParams?.includes("cropRight")) {
2359
+ device.setDisplayCropRight(drawCropRight);
2360
+ }
2361
+ if (updatedParams?.includes("cropBottom")) {
2362
+ device.setDisplayCropBottom(drawCropBottom);
2363
+ }
2364
+ if (updatedParams?.includes("cropLeft")) {
2365
+ device.setDisplayCropLeft(drawCropLeft);
2366
+ }
2367
+
2368
+ if (updatedParams?.includes("rotationCropTop")) {
2369
+ device.setDisplayRotationCropTop(drawRotationCropTop);
2370
+ }
2371
+ if (updatedParams?.includes("rotationCropRight")) {
2372
+ device.setDisplayRotationCropRight(drawRotationCropRight);
2373
+ }
2374
+ if (updatedParams?.includes("rotationCropBottom")) {
2375
+ device.setDisplayRotationCropBottom(drawRotationCropBottom);
2376
+ }
2377
+ if (updatedParams?.includes("rotationCropLeft")) {
2378
+ device.setDisplayRotationCropLeft(drawRotationCropLeft);
2379
+ }
2380
+
2381
+ if (updatedParams?.includes("bitmapScaleX")) {
2382
+ device.setDisplayBitmapScaleX(drawBitmapScaleX);
2383
+ }
2384
+ if (updatedParams?.includes("bitmapScaleY")) {
2385
+ device.setDisplayBitmapScaleY(drawBitmapScaleY);
2386
+ }
2387
+ if (updatedParams?.includes("bitmapScale")) {
2388
+ device.setDisplayBitmapScale(drawBitmapScale);
2389
+ }
2390
+
2391
+ switch (drawShapeType) {
2392
+ case "drawRect":
2393
+ device.drawDisplayRect(drawX, drawY, drawWidth, drawHeight);
2394
+ break;
2395
+ case "drawRoundRect":
2396
+ device.drawDisplayRoundRect(
2397
+ drawX,
2398
+ drawY,
2399
+ drawWidth,
2400
+ drawHeight,
2401
+ drawBorderRadius
2402
+ );
2403
+ break;
2404
+ case "drawCircle":
2405
+ device.drawDisplayCircle(drawX, drawY, drawRadius);
2406
+ break;
2407
+ case "drawEllipse":
2408
+ device.drawDisplayEllipse(drawX, drawY, drawWidth, drawHeight);
2409
+ break;
2410
+ case "drawRegularPolygon":
2411
+ device.drawDisplayRegularPolygon(
2412
+ drawX,
2413
+ drawY,
2414
+ drawRadius,
2415
+ drawNumberOfSides
2416
+ );
2417
+ break;
2418
+ case "drawSegment":
2419
+ device.drawDisplaySegment(drawX, drawY, drawEndX, drawEndY);
2420
+ break;
2421
+ case "drawArc":
2422
+ device.drawDisplayArc(
2423
+ drawX,
2424
+ drawY,
2425
+ drawRadius,
2426
+ drawStartAngle,
2427
+ drawAngleOffset
2428
+ );
2429
+ break;
2430
+ case "drawArcEllipse":
2431
+ device.drawDisplayArcEllipse(
2432
+ drawX,
2433
+ drawY,
2434
+ drawWidth,
2435
+ drawHeight,
2436
+ drawStartAngle,
2437
+ drawAngleOffset
2438
+ );
2439
+ break;
2440
+ case "drawBitmap":
2441
+ device.drawDisplayBitmap(drawX, drawY, {
2442
+ numberOfColors: bitmapNumberOfColors,
2443
+ pixels: bitmapPixels,
2444
+ width: bitmapWidth,
2445
+ height: bitmapHeight,
2446
+ });
2447
+ break;
2448
+ default:
2449
+ console.error(`uncaught drawShapeType ${drawShapeType}`);
2450
+ break;
2451
+ }
2452
+ device.showDisplay();
2453
+ }
2454
+ };
2455
+
2456
+ const lineWidthContainer = document.getElementById("lineWidth");
2457
+ const lineWidthInput = lineWidthContainer.querySelector("input");
2458
+ const lineWidthSpan = lineWidthContainer.querySelector("span");
2459
+ let lineWidth = Number(lineWidthInput.value);
2460
+
2461
+ lineWidthInput.addEventListener("input", () => {
2462
+ lineWidth = Number(lineWidthInput.value);
2463
+ //console.log({ lineWidth });
2464
+ lineWidthSpan.innerText = lineWidth;
2465
+
2466
+ drawShape(["lineWidth"]);
2467
+ });
2468
+
2469
+ const rotationContainer = document.getElementById("rotation");
2470
+ const rotationInput = rotationContainer.querySelector("input");
2471
+ const rotationSpan = rotationContainer.querySelector("span");
2472
+ let rotation = Number(rotationInput.value);
2473
+
2474
+ rotationInput.addEventListener("input", () => {
2475
+ rotation = Number(rotationInput.value);
2476
+ // console.log({ rotation });
2477
+ rotationSpan.innerText = rotation;
2478
+
2479
+ drawShape(["rotation"]);
2480
+ });
2481
+
2482
+ const horizontalAlignmentContainer = document.getElementById(
2483
+ "horizontalAlignment"
2484
+ );
2485
+ const horizontalAlignmentSelect =
2486
+ horizontalAlignmentContainer.querySelector("select");
2487
+ const horizontalAlignmentOptgroup =
2488
+ horizontalAlignmentSelect.querySelector("optgroup");
2489
+
2490
+ BS.DisplayAlignments.forEach((horizontalAlignment) => {
2491
+ horizontalAlignmentOptgroup.appendChild(new Option(horizontalAlignment));
2492
+ });
2493
+ horizontalAlignmentSelect.value = "center";
2494
+ let horizontalAlignment = horizontalAlignmentSelect.value;
2495
+ console.log({ horizontalAlignment });
2496
+
2497
+ horizontalAlignmentSelect.addEventListener("input", () => {
2498
+ horizontalAlignment = horizontalAlignmentSelect.value;
2499
+ console.log({ horizontalAlignment });
2500
+ drawShape(["horizontalAlignment"]);
2501
+ });
2502
+
2503
+ const verticalAlignmentContainer = document.getElementById("verticalAlignment");
2504
+ const verticalAlignmentSelect =
2505
+ verticalAlignmentContainer.querySelector("select");
2506
+ const verticalAlignmentOptgroup =
2507
+ verticalAlignmentSelect.querySelector("optgroup");
2508
+
2509
+ BS.DisplayAlignments.forEach((verticalAlignment) => {
2510
+ verticalAlignmentOptgroup.appendChild(new Option(verticalAlignment));
2511
+ });
2512
+ verticalAlignmentSelect.value = "center";
2513
+ let verticalAlignment = verticalAlignmentSelect.value;
2514
+ console.log({ verticalAlignment });
2515
+
2516
+ verticalAlignmentSelect.addEventListener("input", () => {
2517
+ verticalAlignment = verticalAlignmentSelect.value;
2518
+ console.log({ verticalAlignment });
2519
+ drawShape(["verticalAlignment"]);
2520
+ });
2521
+
2522
+ const segmentStartCapContainer = document.getElementById("segmentStartCap");
2523
+ const segmentStartCapSelect = segmentStartCapContainer.querySelector("select");
2524
+ const segmentStartCapOptgroup = segmentStartCapSelect.querySelector("optgroup");
2525
+
2526
+ BS.DisplaySegmentCaps.forEach((segmentStartCap) => {
2527
+ segmentStartCapOptgroup.appendChild(new Option(segmentStartCap));
2528
+ });
2529
+ let segmentStartCap = segmentStartCapSelect.value;
2530
+ console.log({ segmentStartCap });
2531
+
2532
+ segmentStartCapSelect.addEventListener("input", () => {
2533
+ segmentStartCap = segmentStartCapSelect.value;
2534
+ console.log({ segmentStartCap });
2535
+ drawShape(["segmentStartCap"]);
2536
+ });
2537
+
2538
+ const segmentEndCapContainer = document.getElementById("segmentEndCap");
2539
+ const segmentEndCapSelect = segmentEndCapContainer.querySelector("select");
2540
+ const segmentEndCapOptgroup = segmentEndCapSelect.querySelector("optgroup");
2541
+
2542
+ BS.DisplaySegmentCaps.forEach((segmentEndCap) => {
2543
+ segmentEndCapOptgroup.appendChild(new Option(segmentEndCap));
2544
+ });
2545
+ let segmentEndCap = segmentEndCapSelect.value;
2546
+ console.log({ segmentEndCap });
2547
+
2548
+ segmentEndCapSelect.addEventListener("input", () => {
2549
+ segmentEndCap = segmentEndCapSelect.value;
2550
+ console.log({ segmentEndCap });
2551
+ drawShape(["segmentEndCap"]);
2552
+ });
2553
+
2554
+ const drawSegmentStartRadiusContainer = document.getElementById(
2555
+ "drawSegmentStartRadius"
2556
+ );
2557
+ const drawSegmentStartRadiusInput =
2558
+ drawSegmentStartRadiusContainer.querySelector("input");
2559
+ const drawSegmentStartRadiusSpan =
2560
+ drawSegmentStartRadiusContainer.querySelector("span");
2561
+ let drawSegmentStartRadius = Number(drawSegmentStartRadiusInput.value);
2562
+
2563
+ drawSegmentStartRadiusInput.addEventListener("input", () => {
2564
+ drawSegmentStartRadius = Number(drawSegmentStartRadiusInput.value);
2565
+ //console.log({ drawSegmentStartRadius });
2566
+ drawSegmentStartRadiusSpan.innerText = drawSegmentStartRadius;
2567
+ drawShape(["segmentStartRadius"]);
2568
+ });
2569
+
2570
+ const drawSegmentEndRadiusContainer = document.getElementById(
2571
+ "drawSegmentEndRadius"
2572
+ );
2573
+ const drawSegmentEndRadiusInput =
2574
+ drawSegmentEndRadiusContainer.querySelector("input");
2575
+ const drawSegmentEndRadiusSpan =
2576
+ drawSegmentEndRadiusContainer.querySelector("span");
2577
+ let drawSegmentEndRadius = Number(drawSegmentEndRadiusInput.value);
2578
+
2579
+ drawSegmentEndRadiusInput.addEventListener("input", () => {
2580
+ drawSegmentEndRadius = Number(drawSegmentEndRadiusInput.value);
2581
+ //console.log({ drawSegmentEndRadius });
2582
+ drawSegmentEndRadiusSpan.innerText = drawSegmentEndRadius;
2583
+ drawShape(["segmentEndRadius"]);
2584
+ });
2585
+
2586
+ const drawCropTopContainer = document.getElementById("drawCropTop");
2587
+ const drawCropTopInput = drawCropTopContainer.querySelector("input");
2588
+ const drawCropTopSpan = drawCropTopContainer.querySelector("span");
2589
+ let drawCropTop = Number(drawCropTopInput.value);
2590
+
2591
+ drawCropTopInput.addEventListener("input", () => {
2592
+ drawCropTop = Number(drawCropTopInput.value);
2593
+ //console.log({ drawCropTop });
2594
+ drawCropTopSpan.innerText = drawCropTop;
2595
+ drawShape(["cropTop"]);
2596
+ });
2597
+
2598
+ const drawCropRightContainer = document.getElementById("drawCropRight");
2599
+ const drawCropRightInput = drawCropRightContainer.querySelector("input");
2600
+ const drawCropRightSpan = drawCropRightContainer.querySelector("span");
2601
+ let drawCropRight = Number(drawCropRightInput.value);
2602
+
2603
+ drawCropRightInput.addEventListener("input", () => {
2604
+ drawCropRight = Number(drawCropRightInput.value);
2605
+ //console.log({ drawCropRight });
2606
+ drawCropRightSpan.innerText = drawCropRight;
2607
+ drawShape(["cropRight"]);
2608
+ });
2609
+
2610
+ const drawCropBottomContainer = document.getElementById("drawCropBottom");
2611
+ const drawCropBottomInput = drawCropBottomContainer.querySelector("input");
2612
+ const drawCropBottomSpan = drawCropBottomContainer.querySelector("span");
2613
+ let drawCropBottom = Number(drawCropBottomInput.value);
2614
+
2615
+ drawCropBottomInput.addEventListener("input", () => {
2616
+ drawCropBottom = Number(drawCropBottomInput.value);
2617
+ //console.log({ drawCropBottom });
2618
+ drawCropBottomSpan.innerText = drawCropBottom;
2619
+ drawShape(["cropBottom"]);
2620
+ });
2621
+
2622
+ const drawCropLeftContainer = document.getElementById("drawCropLeft");
2623
+ const drawCropLeftInput = drawCropLeftContainer.querySelector("input");
2624
+ const drawCropLeftSpan = drawCropLeftContainer.querySelector("span");
2625
+ let drawCropLeft = Number(drawCropLeftInput.value);
2626
+
2627
+ drawCropLeftInput.addEventListener("input", () => {
2628
+ drawCropLeft = Number(drawCropLeftInput.value);
2629
+ //console.log({ drawCropLeft });
2630
+ drawCropLeftSpan.innerText = drawCropLeft;
2631
+ drawShape(["cropLeft"]);
2632
+ });
2633
+
2634
+ const drawRotationCropTopContainer = document.getElementById(
2635
+ "drawRotationCropTop"
2636
+ );
2637
+ const drawRotationCropTopInput =
2638
+ drawRotationCropTopContainer.querySelector("input");
2639
+ const drawRotationCropTopSpan =
2640
+ drawRotationCropTopContainer.querySelector("span");
2641
+ let drawRotationCropTop = Number(drawRotationCropTopInput.value);
2642
+
2643
+ drawRotationCropTopInput.addEventListener("input", () => {
2644
+ drawRotationCropTop = Number(drawRotationCropTopInput.value);
2645
+ //console.log({ drawRotationCropTop });
2646
+ drawRotationCropTopSpan.innerText = drawRotationCropTop;
2647
+ drawShape(["rotationCropTop"]);
2648
+ });
2649
+
2650
+ const drawRotationCropRightContainer = document.getElementById(
2651
+ "drawRotationCropRight"
2652
+ );
2653
+ const drawRotationCropRightInput =
2654
+ drawRotationCropRightContainer.querySelector("input");
2655
+ const drawRotationCropRightSpan =
2656
+ drawRotationCropRightContainer.querySelector("span");
2657
+ let drawRotationCropRight = Number(drawRotationCropRightInput.value);
2658
+
2659
+ drawRotationCropRightInput.addEventListener("input", () => {
2660
+ drawRotationCropRight = Number(drawRotationCropRightInput.value);
2661
+ //console.log({ drawRotationCropRight });
2662
+ drawRotationCropRightSpan.innerText = drawRotationCropRight;
2663
+ drawShape(["rotationCropRight"]);
2664
+ });
2665
+
2666
+ const drawRotationCropBottomContainer = document.getElementById(
2667
+ "drawRotationCropBottom"
2668
+ );
2669
+ const drawRotationCropBottomInput =
2670
+ drawRotationCropBottomContainer.querySelector("input");
2671
+ const drawRotationCropBottomSpan =
2672
+ drawRotationCropBottomContainer.querySelector("span");
2673
+ let drawRotationCropBottom = Number(drawRotationCropBottomInput.value);
2674
+
2675
+ drawRotationCropBottomInput.addEventListener("input", () => {
2676
+ drawRotationCropBottom = Number(drawRotationCropBottomInput.value);
2677
+ //console.log({ drawRotationCropBottom });
2678
+ drawRotationCropBottomSpan.innerText = drawRotationCropBottom;
2679
+ drawShape(["rotationCropBottom"]);
2680
+ });
2681
+
2682
+ const drawRotationCropLeftContainer = document.getElementById(
2683
+ "drawRotationCropLeft"
2684
+ );
2685
+ const drawRotationCropLeftInput =
2686
+ drawRotationCropLeftContainer.querySelector("input");
2687
+ const drawRotationCropLeftSpan =
2688
+ drawRotationCropLeftContainer.querySelector("span");
2689
+ let drawRotationCropLeft = Number(drawRotationCropLeftInput.value);
2690
+
2691
+ drawRotationCropLeftInput.addEventListener("input", () => {
2692
+ drawRotationCropLeft = Number(drawRotationCropLeftInput.value);
2693
+ //console.log({ drawRotationCropLeft });
2694
+ drawRotationCropLeftSpan.innerText = drawRotationCropLeft;
2695
+ drawShape(["rotationCropLeft"]);
2696
+ });
2697
+
2698
+ const drawBitmapScaleXContainer = document.getElementById("drawBitmapScaleX");
2699
+ const drawBitmapScaleXInput = drawBitmapScaleXContainer.querySelector("input");
2700
+ const drawBitmapScaleXSpan = drawBitmapScaleXContainer.querySelector("span");
2701
+ let drawBitmapScaleX = Number(drawBitmapScaleXInput.value);
2702
+
2703
+ drawBitmapScaleXInput.addEventListener("input", () => {
2704
+ drawBitmapScaleX = Number(drawBitmapScaleXInput.value);
2705
+ //console.log({ drawBitmapScaleX });
2706
+ drawBitmapScaleXSpan.innerText = drawBitmapScaleX;
2707
+ drawShape(["bitmapScaleX"]);
2708
+ });
2709
+
2710
+ const drawBitmapScaleYContainer = document.getElementById("drawBitmapScaleY");
2711
+ const drawBitmapScaleYInput = drawBitmapScaleYContainer.querySelector("input");
2712
+ const drawBitmapScaleYSpan = drawBitmapScaleYContainer.querySelector("span");
2713
+ let drawBitmapScaleY = Number(drawBitmapScaleYInput.value);
2714
+
2715
+ drawBitmapScaleYInput.addEventListener("input", () => {
2716
+ drawBitmapScaleY = Number(drawBitmapScaleYInput.value);
2717
+ //console.log({ drawBitmapScaleY });
2718
+ drawBitmapScaleYSpan.innerText = drawBitmapScaleY;
2719
+ drawShape(["bitmapScaleY"]);
2720
+ });
2721
+
2722
+ const drawBitmapScaleContainer = document.getElementById("drawBitmapScale");
2723
+ const drawBitmapScaleInput = drawBitmapScaleContainer.querySelector("input");
2724
+ const drawBitmapScaleSpan = drawBitmapScaleContainer.querySelector("span");
2725
+ let drawBitmapScale = Number(drawBitmapScaleInput.value);
2726
+
2727
+ drawBitmapScaleInput.addEventListener("input", () => {
2728
+ drawBitmapScale = Number(drawBitmapScaleInput.value);
2729
+ //console.log({ drawBitmapScale });
2730
+
2731
+ drawBitmapScaleXSpan.innerText = drawBitmapScale;
2732
+ drawBitmapScaleXInput.value = drawBitmapScale;
2733
+
2734
+ drawBitmapScaleYSpan.innerText = drawBitmapScale;
2735
+ drawBitmapScaleYInput.value = drawBitmapScale;
2736
+
2737
+ drawBitmapScaleSpan.innerText = drawBitmapScale;
2738
+ drawShape(["bitmapScale"]);
2739
+ });
2740
+
2741
+ const drawXContainer = document.getElementById("drawX");
2742
+ const drawXInput = drawXContainer.querySelector("input");
2743
+ const drawXSpan = drawXContainer.querySelector("span");
2744
+ let drawX = Number(drawXInput.value);
2745
+
2746
+ drawXInput.addEventListener("input", () => {
2747
+ drawX = Number(drawXInput.value);
2748
+ //console.log({ drawX });
2749
+ drawXSpan.innerText = drawX;
2750
+ drawShape();
2751
+ });
2752
+
2753
+ const drawYContainer = document.getElementById("drawY");
2754
+ const drawYInput = drawYContainer.querySelector("input");
2755
+ const drawYSpan = drawYContainer.querySelector("span");
2756
+ let drawY = Number(drawYInput.value);
2757
+
2758
+ drawYInput.addEventListener("input", () => {
2759
+ drawY = Number(drawYInput.value);
2760
+ //console.log({ drawY });
2761
+ drawYSpan.innerText = drawY;
2762
+ drawShape();
2763
+ });
2764
+
2765
+ const drawWidthContainer = document.getElementById("drawWidth");
2766
+ const drawWidthInput = drawWidthContainer.querySelector("input");
2767
+ const drawWidthSpan = drawWidthContainer.querySelector("span");
2768
+ let drawWidth = Number(drawWidthInput.value);
2769
+
2770
+ drawWidthInput.addEventListener("input", () => {
2771
+ drawWidth = Number(drawWidthInput.value);
2772
+ //console.log({ drawWidth });
2773
+ drawWidthSpan.innerText = drawWidth;
2774
+ drawShape();
2775
+ });
2776
+
2777
+ const drawHeightContainer = document.getElementById("drawHeight");
2778
+ const drawHeightInput = drawHeightContainer.querySelector("input");
2779
+ const drawHeightSpan = drawHeightContainer.querySelector("span");
2780
+ let drawHeight = Number(drawHeightInput.value);
2781
+
2782
+ drawHeightInput.addEventListener("input", () => {
2783
+ drawHeight = Number(drawHeightInput.value);
2784
+ //console.log({ drawHeight });
2785
+ drawHeightSpan.innerText = drawHeight;
2786
+ drawShape();
2787
+ });
2788
+
2789
+ const drawRadiusContainer = document.getElementById("drawRadius");
2790
+ const drawRadiusInput = drawRadiusContainer.querySelector("input");
2791
+ const drawRadiusSpan = drawRadiusContainer.querySelector("span");
2792
+ let drawRadius = Number(drawRadiusInput.value);
2793
+
2794
+ drawRadiusInput.addEventListener("input", () => {
2795
+ drawRadius = Number(drawRadiusInput.value);
2796
+ //console.log({ drawRadius });
2797
+ drawRadiusSpan.innerText = drawRadius;
2798
+ drawShape();
2799
+ });
2800
+
2801
+ const drawBorderRadiusContainer = document.getElementById("drawBorderRadius");
2802
+ const drawBorderRadiusInput = drawBorderRadiusContainer.querySelector("input");
2803
+ const drawBorderRadiusSpan = drawBorderRadiusContainer.querySelector("span");
2804
+ let drawBorderRadius = Number(drawBorderRadiusInput.value);
2805
+
2806
+ drawBorderRadiusInput.addEventListener("input", () => {
2807
+ drawBorderRadius = Number(drawBorderRadiusInput.value);
2808
+ //console.log({ drawBorderRadius });
2809
+ drawBorderRadiusSpan.innerText = drawBorderRadius;
2810
+ drawShape();
2811
+ });
2812
+
2813
+ const drawNumberOfSidesContainer = document.getElementById("drawNumberOfSides");
2814
+ const drawNumberOfSidesInput =
2815
+ drawNumberOfSidesContainer.querySelector("input");
2816
+ const drawNumberOfSidesSpan = drawNumberOfSidesContainer.querySelector("span");
2817
+ let drawNumberOfSides = Number(drawNumberOfSidesInput.value);
2818
+
2819
+ drawNumberOfSidesInput.addEventListener("input", () => {
2820
+ drawNumberOfSides = Number(drawNumberOfSidesInput.value);
2821
+ //console.log({ drawNumberOfSides });
2822
+ drawNumberOfSidesSpan.innerText = drawNumberOfSides;
2823
+ drawShape();
2824
+ });
2825
+
2826
+ const drawEndXContainer = document.getElementById("drawEndX");
2827
+ const drawEndXInput = drawEndXContainer.querySelector("input");
2828
+ const drawEndXSpan = drawEndXContainer.querySelector("span");
2829
+ let drawEndX = Number(drawEndXInput.value);
2830
+
2831
+ drawEndXInput.addEventListener("input", () => {
2832
+ drawEndX = Number(drawEndXInput.value);
2833
+ //console.log({ drawEndX });
2834
+ drawEndXSpan.innerText = drawEndX;
2835
+ drawShape();
2836
+ });
2837
+
2838
+ const drawEndYContainer = document.getElementById("drawEndY");
2839
+ const drawEndYInput = drawEndYContainer.querySelector("input");
2840
+ const drawEndYSpan = drawEndYContainer.querySelector("span");
2841
+ let drawEndY = Number(drawEndYInput.value);
2842
+
2843
+ drawEndYInput.addEventListener("input", () => {
2844
+ drawEndY = Number(drawEndYInput.value);
2845
+ //console.log({ drawEndY });
2846
+ drawEndYSpan.innerText = drawEndY;
2847
+ drawShape();
2848
+ });
2849
+
2850
+ const drawStartAngleContainer = document.getElementById("drawStartAngle");
2851
+ const drawStartAngleInput = drawStartAngleContainer.querySelector("input");
2852
+ const drawStartAngleSpan = drawStartAngleContainer.querySelector("span");
2853
+ let drawStartAngle = Number(drawStartAngleInput.value);
2854
+
2855
+ drawStartAngleInput.addEventListener("input", () => {
2856
+ drawStartAngle = Number(drawStartAngleInput.value);
2857
+ //console.log({ drawStartAngle });
2858
+ drawStartAngleSpan.innerText = drawStartAngle;
2859
+ drawShape();
2860
+ });
2861
+
2862
+ const drawAngleOffsetContainer = document.getElementById("drawAngleOffset");
2863
+ const drawAngleOffsetInput = drawAngleOffsetContainer.querySelector("input");
2864
+ const drawAngleOffsetSpan = drawAngleOffsetContainer.querySelector("span");
2865
+ let drawAngleOffset = Number(drawAngleOffsetInput.value);
2866
+
2867
+ drawAngleOffsetInput.addEventListener("input", () => {
2868
+ drawAngleOffset = Number(drawAngleOffsetInput.value);
2869
+ //console.log({ drawAngleOffset });
2870
+ drawAngleOffsetSpan.innerText = drawAngleOffset;
2871
+ drawShape();
2872
+ });
2873
+
2874
+ /** @type {HTMLButtonElement} */
2875
+ const drawShapeButton = document.getElementById("drawShape");
2876
+ drawShapeButton.addEventListener("click", () => {
2877
+ drawShape();
2878
+ });
2879
+ device.addEventListener("isConnected", () => {
2880
+ const enabled = device.isConnected && device.isDisplayAvailable;
2881
+ drawShapeButton.disabled = !enabled;
2882
+ });
2883
+
2884
+ /** @type {HTMLSelectElement} */
2885
+ const drawShapeTypeSelect = document.getElementById("drawShapeType");
2886
+ let drawShapeType = drawShapeTypeSelect.value;
2887
+ drawShapeTypeSelect.addEventListener("input", () => {
2888
+ drawShapeType = drawShapeTypeSelect.value;
2889
+ console.log({ drawShapeType });
2890
+ drawShape();
2891
+ });
2892
+ console.log({ drawShapeType });
2893
+
2894
+ device.addEventListener("connected", () => {
2895
+ if (!device.isDisplayAvailable) {
2896
+ return;
2897
+ }
2898
+ drawXInput.max = device.displayInformation.width + 50;
2899
+ drawYInput.max = device.displayInformation.height + 50;
2900
+
2901
+ drawWidthInput.max = device.displayInformation.width;
2902
+ drawHeightInput.max = device.displayInformation.height;
2903
+
2904
+ drawRadiusInput.max = Math.min(
2905
+ device.displayInformation.height / 2,
2906
+ device.displayInformation.width / 2
2907
+ );
2908
+ });
2909
+
2910
+ // BITMAP
2911
+ const bitmapWidthContainer = document.getElementById("bitmapWidth");
2912
+ const bitmapWidthInput = bitmapWidthContainer.querySelector("input");
2913
+ const bitmapWidthSpan = bitmapWidthContainer.querySelector("span");
2914
+ let bitmapWidth = Number(bitmapWidthInput.value);
2915
+
2916
+ bitmapWidthInput.addEventListener("input", () => {
2917
+ bitmapWidth = Number(bitmapWidthInput.value);
2918
+ console.log({ bitmapWidth });
2919
+ bitmapWidthSpan.innerText = bitmapWidth;
2920
+ onBitmapCanvasSizeUpdate();
2921
+ });
2922
+
2923
+ const bitmapHeightContainer = document.getElementById("bitmapHeight");
2924
+ const bitmapHeightInput = bitmapHeightContainer.querySelector("input");
2925
+ const bitmapHeightSpan = bitmapHeightContainer.querySelector("span");
2926
+ let bitmapHeight = Number(bitmapHeightInput.value);
2927
+
2928
+ bitmapHeightInput.addEventListener("input", () => {
2929
+ bitmapHeight = Number(bitmapHeightInput.value);
2930
+ console.log({ bitmapHeight });
2931
+ bitmapHeightSpan.innerText = bitmapHeight;
2932
+ onBitmapCanvasSizeUpdate();
2933
+ });
2934
+
2935
+ let bitmapPixels = [];
2936
+ const bitmapContainer = document.getElementById("bitmap");
2937
+ const bitmapCanvas = bitmapContainer.querySelector("canvas");
2938
+ const bitmapContext = bitmapCanvas.getContext("2d");
2939
+ const bitmapCanvasHeight = 200;
2940
+ let bitmapPixelLength = bitmapCanvasHeight / bitmapHeight;
2941
+ let bitmapAspectRatio = bitmapWidth / bitmapHeight;
2942
+ let bitmapCanvasWidth = bitmapCanvasHeight * bitmapAspectRatio;
2943
+ const onBitmapCanvasSizeUpdate = () => {
2944
+ bitmapAspectRatio = bitmapWidth / bitmapHeight;
2945
+ bitmapCanvasWidth = bitmapCanvasHeight * bitmapAspectRatio;
2946
+ bitmapCanvas.style.width = `${bitmapCanvasWidth}px`;
2947
+
2948
+ bitmapPixels = new Array(bitmapWidth * bitmapHeight).fill(0);
2949
+
2950
+ bitmapPixelLength = bitmapCanvasHeight / bitmapHeight;
2951
+
2952
+ bitmapCanvas.width = bitmapPixelLength * bitmapWidth;
2953
+ bitmapCanvas.height = bitmapPixelLength * bitmapHeight;
2954
+
2955
+ bitmapImage.width = bitmapCanvas.width;
2956
+ bitmapImage.height = bitmapCanvas.height;
2957
+ bitmapImage.style.width = `${bitmapCanvas.width}px`;
2958
+ quantizedBitmapImage.style.width = `${bitmapCanvas.width}px`;
2959
+
2960
+ updateBitmapCanvas();
2961
+ };
2962
+ const updateBitmapCanvas = () => {
2963
+ bitmapContext.clearRect(0, 0, bitmapCanvasWidth, bitmapCanvasHeight);
2964
+ bitmapContext.fillStyle = device.displayBitmapColors[0];
2965
+ bitmapContext.fillRect(0, 0, bitmapCanvasWidth, bitmapCanvasHeight);
2966
+
2967
+ bitmapPixels.forEach((pixel, pixelIndex) => {
2968
+ const pixelX = pixelIndex % bitmapWidth;
2969
+ const pixelY = Math.floor(pixelIndex / bitmapWidth);
2970
+ const x = pixelX * bitmapPixelLength;
2971
+ const y = pixelY * bitmapPixelLength;
2972
+ bitmapContext.fillStyle = device.displayBitmapColors[pixel];
2973
+ bitmapContext.fillRect(x, y, bitmapPixelLength, bitmapPixelLength);
2974
+ });
2975
+
2976
+ bitmapContext.lineWidth = 1.5;
2977
+ bitmapContext.strokeStyle = "white";
2978
+ for (let row = 1; row < bitmapHeight; row++) {
2979
+ bitmapContext.beginPath();
2980
+ const y = row * bitmapPixelLength;
2981
+ bitmapContext.moveTo(0, y);
2982
+ bitmapContext.lineTo(bitmapCanvasWidth, y);
2983
+ bitmapContext.stroke();
2984
+ }
2985
+ for (let col = 1; col < bitmapWidth; col++) {
2986
+ bitmapContext.beginPath();
2987
+ const x = col * bitmapPixelLength;
2988
+ bitmapContext.moveTo(x, 0);
2989
+ bitmapContext.lineTo(x, bitmapCanvasHeight);
2990
+ bitmapContext.stroke();
2991
+ }
2992
+
2993
+ drawShape();
2994
+ };
2995
+ let isMouseDown = false;
2996
+ window.addEventListener("mousedown", () => {
2997
+ isMouseDown = true;
2998
+ });
2999
+ window.addEventListener("mouseup", () => {
3000
+ isMouseDown = false;
3001
+ });
3002
+ bitmapCanvas.addEventListener("mousedown", (event) => {
3003
+ const { offsetX, offsetY } = event;
3004
+ setBitmapPixel(offsetX, offsetY);
3005
+ });
3006
+ bitmapCanvas.addEventListener("mousemove", (event) => {
3007
+ if (!isMouseDown) {
3008
+ return;
3009
+ }
3010
+ const { offsetX, offsetY } = event;
3011
+ setBitmapPixel(offsetX, offsetY);
3012
+ });
3013
+ /**
3014
+ * @param {number} offsetX
3015
+ * @param {number} offsetY
3016
+ */
3017
+ const setBitmapPixel = (offsetX, offsetY) => {
3018
+ console.log({ offsetX, offsetY, bitmapCanvasWidth, bitmapCanvasHeight });
3019
+ let x = offsetX / bitmapCanvasWidth;
3020
+ let y = offsetY / bitmapCanvasHeight;
3021
+ if (x >= 1 || y >= 1) {
3022
+ return;
3023
+ }
3024
+ // console.log({ x, y });
3025
+ const pixelX = Math.floor(x * bitmapWidth);
3026
+ const pixelY = Math.floor(y * bitmapHeight);
3027
+ // console.log({ pixelX, pixelY });
3028
+
3029
+ const pixelIndex = bitmapWidth * pixelY + pixelX;
3030
+ // console.log({ pixelIndex });
3031
+
3032
+ bitmapPixels[pixelIndex] = currentBitmapColorIndex;
3033
+ updateBitmapCanvas();
3034
+ };
3035
+
3036
+ const bitmapNumberOfColorsContainer = document.getElementById(
3037
+ "bitmapNumberOfColors"
3038
+ );
3039
+ const bitmapNumberOfColorsInput =
3040
+ bitmapNumberOfColorsContainer.querySelector("input");
3041
+ const bitmapNumberOfColorsSpan =
3042
+ bitmapNumberOfColorsContainer.querySelector("span");
3043
+ let bitmapNumberOfColors = Number(bitmapNumberOfColorsInput.value);
3044
+
3045
+ bitmapNumberOfColorsInput.addEventListener("input", () => {
3046
+ bitmapNumberOfColors = Number(bitmapNumberOfColorsInput.value);
3047
+ bitmapPixels.fill(0);
3048
+ console.log({ bitmapNumberOfColors });
3049
+ bitmapNumberOfColorsSpan.innerText = bitmapNumberOfColors;
3050
+ updateBitmapColorIndicesContainer();
3051
+ updateCurrentBitmapColorIndex();
3052
+ updateCurrentBitmapColor();
3053
+ updateBitmapCanvas();
3054
+ });
3055
+
3056
+ const bitmapColorIndicesContainer =
3057
+ document.getElementById("bitmapColorIndices");
3058
+ /** @type {HTMLTemplateElement} */
3059
+ const bitmapColorIndexTemplate = document.getElementById(
3060
+ "bitmapColorIndexTemplate"
3061
+ );
3062
+ const updateBitmapColorIndicesContainer = () => {
3063
+ bitmapColorIndicesContainer.innerHTML = "";
3064
+ if (!device.isConnected) {
3065
+ return;
3066
+ }
3067
+ for (
3068
+ let bitmapColorIndex = 0;
3069
+ bitmapColorIndex < bitmapNumberOfColors;
3070
+ bitmapColorIndex++
3071
+ ) {
3072
+ /** @type {HTMLElement} */
3073
+ const bitmapColorIndexContainer = bitmapColorIndexTemplate.content
3074
+ .cloneNode(true)
3075
+ .querySelector(".bitmapColorIndex");
3076
+
3077
+ const bitmapColorIndexSpan =
3078
+ bitmapColorIndexContainer.querySelector(".colorIndex");
3079
+ bitmapColorIndexSpan.innerText = `#${bitmapColorIndex}`;
3080
+ const bitmapColorIndexSelect =
3081
+ bitmapColorIndexContainer.querySelector("select");
3082
+ const bitmapColorIndexOptgroup =
3083
+ bitmapColorIndexSelect.querySelector("optgroup");
3084
+ const numberOfDisplayColors = device.isConnected
3085
+ ? device.numberOfDisplayColors
3086
+ : 0;
3087
+ for (let colorIndex = 0; colorIndex < numberOfDisplayColors; colorIndex++) {
3088
+ bitmapColorIndexOptgroup.appendChild(new Option(colorIndex));
3089
+ }
3090
+
3091
+ const bitmapColorIndexColorInput =
3092
+ bitmapColorIndexContainer.querySelector("input");
3093
+ bitmapColorIndexColorInput.value =
3094
+ device.displayBitmapColors[bitmapColorIndex];
3095
+
3096
+ bitmapColorIndexSelect.value =
3097
+ device.displayBitmapColorIndices[bitmapColorIndex];
3098
+ bitmapColorIndexSelect.addEventListener("input", () => {
3099
+ const colorIndex = Number(bitmapColorIndexSelect.value);
3100
+ if (device.isConnected) {
3101
+ device.selectDisplayBitmapColor(bitmapColorIndex, colorIndex, true);
3102
+ }
3103
+ bitmapColorIndexColorInput.value = device.displayColors[colorIndex];
3104
+
3105
+ if (currentBitmapColorIndex == bitmapColorIndex) {
3106
+ updateCurrentBitmapColor();
3107
+ }
3108
+ console.log(
3109
+ "bitmapColorIndices",
3110
+ device.displayContextState.bitmapColorIndices
3111
+ );
3112
+ updateBitmapCanvas();
3113
+ });
3114
+
3115
+ bitmapColorIndicesContainer.appendChild(bitmapColorIndexContainer);
3116
+ }
3117
+ };
3118
+ device.addEventListener("isConnected", () => {
3119
+ updateBitmapColorIndicesContainer();
3120
+ });
3121
+
3122
+ const currentBitmapColorIndexContainer = document.getElementById(
3123
+ "currentBitmapColorIndex"
3124
+ );
3125
+ let currentBitmapColorIndex = 0;
3126
+ const currentBitmapColorIndexSelect =
3127
+ currentBitmapColorIndexContainer.querySelector("select");
3128
+ const currentBitmapColorIndexOptgroup =
3129
+ currentBitmapColorIndexContainer.querySelector("optgroup");
3130
+ const currentBitmapColorIndexColorInput =
3131
+ currentBitmapColorIndexContainer.querySelector("input");
3132
+ const updateCurrentBitmapColorIndex = () => {
3133
+ currentBitmapColorIndex = 0;
3134
+ currentBitmapColorIndexOptgroup.innerHTML = "";
3135
+ for (
3136
+ let bitmapColorIndex = 0;
3137
+ bitmapColorIndex < bitmapNumberOfColors;
3138
+ bitmapColorIndex++
3139
+ ) {
3140
+ currentBitmapColorIndexOptgroup.appendChild(new Option(bitmapColorIndex));
3141
+ }
3142
+ };
3143
+ updateCurrentBitmapColorIndex();
3144
+
3145
+ currentBitmapColorIndexSelect.addEventListener("input", () => {
3146
+ currentBitmapColorIndex = Number(currentBitmapColorIndexSelect.value);
3147
+ console.log({ currentBitmapColorIndex });
3148
+ updateCurrentBitmapColor();
3149
+ });
3150
+ const updateCurrentBitmapColor = () => {
3151
+ currentBitmapColorIndexColorInput.value =
3152
+ bitmapColorIndicesContainer.querySelectorAll(".bitmapColorIndex input")[
3153
+ currentBitmapColorIndex
3154
+ ].value;
3155
+ };
3156
+
3157
+ const clearBitmapButton = document.getElementById("clearBitmap");
3158
+ clearBitmapButton.addEventListener("click", () => {
3159
+ bitmapPixels.fill(0);
3160
+ updateBitmapCanvas();
3161
+ });
3162
+
3163
+ /** @type {HTMLInputElement} */
3164
+ const bitmapImageInput = document.getElementById("bitmapImageInput");
3165
+ bitmapImageInput.addEventListener("input", () => {
3166
+ quantizeBitmapImage();
3167
+ });
3168
+ /** @type {HTMLButtonElement} */
3169
+ const quantizeBitmapImageButton = document.getElementById(
3170
+ "quantizeBitmapImage"
3171
+ );
3172
+ quantizeBitmapImageButton.addEventListener("click", () => {
3173
+ quantizeBitmapImage();
3174
+ });
3175
+ const quantizeBitmapImage = () => {
3176
+ const file = bitmapImageInput.files[0];
3177
+ if (!file) {
3178
+ return;
3179
+ }
3180
+ console.log("bitmapImage", file);
3181
+ const reader = new FileReader();
3182
+ reader.onload = function (e) {
3183
+ bitmapImage.style.display = "";
3184
+ bitmapImage.src = e.target.result;
3185
+ };
3186
+ reader.readAsDataURL(file);
3187
+ };
3188
+
3189
+ /** @type {HTMLImageElement} */
3190
+ const bitmapImage = bitmapContainer.querySelectorAll("img")[0];
3191
+ /** @type {HTMLImageElement} */
3192
+ const quantizedBitmapImage = bitmapContainer.querySelectorAll("img")[1];
3193
+ bitmapImage.addEventListener("load", async () => {
3194
+ if (quantizeOverrideDisplayColors) {
3195
+ const { blob, colorIndices, colors } = await device.quantizeDisplayImage(
3196
+ bitmapImage,
3197
+ bitmapWidth,
3198
+ bitmapHeight,
3199
+ bitmapNumberOfColors
3200
+ );
3201
+
3202
+ quantizedBitmapImage.width = bitmapWidth;
3203
+ quantizedBitmapImage.height = bitmapHeight;
3204
+
3205
+ quantizedBitmapImage.src = URL.createObjectURL(blob);
3206
+ quantizedBitmapImage.style.display = "";
3207
+
3208
+ colors.forEach((color, colorIndex) => {
3209
+ device.setDisplayColor(colorIndex, color);
3210
+ device.selectDisplayBitmapColor(colorIndex, colorIndex);
3211
+ });
3212
+ device.flushDisplayContextCommands();
3213
+ } else {
3214
+ const { blob, bitmap } = await device.imageToDisplayBitmap(
3215
+ bitmapImage,
3216
+ bitmapWidth,
3217
+ bitmapHeight,
3218
+ bitmapNumberOfColors
3219
+ );
3220
+
3221
+ quantizedBitmapImage.width = bitmapWidth;
3222
+ quantizedBitmapImage.height = bitmapHeight;
3223
+
3224
+ quantizedBitmapImage.src = URL.createObjectURL(blob);
3225
+ quantizedBitmapImage.style.display = "";
3226
+
3227
+ bitmapPixels = bitmap.pixels;
3228
+ updateBitmapCanvas();
3229
+ }
3230
+ });
3231
+ device.addEventListener("displayContextState", (event) => {
3232
+ const { differences } = event.message;
3233
+ if (differences.includes("bitmapColorIndices")) {
3234
+ const bitmapColorIndexContainers = Array.from(
3235
+ bitmapColorIndicesContainer.querySelectorAll(".bitmapColorIndex")
3236
+ );
3237
+
3238
+ device.displayBitmapColorIndices.forEach((colorIndex, bitmapColorIndex) => {
3239
+ if (bitmapColorIndex >= bitmapNumberOfColors) {
3240
+ return;
3241
+ }
3242
+ const bitmapColorIndexContainer =
3243
+ bitmapColorIndexContainers[bitmapColorIndex];
3244
+ bitmapColorIndexContainer.querySelector("input").value =
3245
+ device.displayColors[colorIndex];
3246
+ bitmapColorIndexContainer.querySelector("select").value = colorIndex;
3247
+ });
3248
+ }
3249
+ });
3250
+
3251
+ const toggleQuantizeOverrideDisplayColorsCheckbox = document.getElementById(
3252
+ "toggleQuantizeOverrideDisplayColors"
3253
+ );
3254
+ let quantizeOverrideDisplayColors =
3255
+ toggleQuantizeOverrideDisplayColorsCheckbox.checked;
3256
+ toggleQuantizeOverrideDisplayColorsCheckbox.addEventListener("input", () => {
3257
+ quantizeOverrideDisplayColors =
3258
+ toggleQuantizeOverrideDisplayColorsCheckbox.checked;
3259
+ });
3260
+ onBitmapCanvasSizeUpdate();