Skip to content

Commit d7d0819

Browse files
committed
Add documentation to app file
1 parent 29adcd8 commit d7d0819

File tree

1 file changed

+47
-26
lines changed
  • libraries/Camera/extras/WebSerialCamera

1 file changed

+47
-26
lines changed

libraries/Camera/extras/WebSerialCamera/app.js

+47-26
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
/**
22
* @fileoverview This file contains the main application logic.
3+
*
4+
* The application uses the Web Serial API to connect to the serial port.
5+
* Check the following links for more information on the Web Serial API:
6+
* https://developer.chrome.com/articles/serial/
7+
* https://wicg.github.io/serial/
8+
*
9+
* The flow of the application is as follows:
10+
* 1. The user clicks the "Connect" button or the browser automatically connects
11+
* to the serial port if it has been previously connected.
12+
* 2. The application requests the camera configuration (mode and resolution) from the board.
13+
* 3. The application starts reading the image data stream from the serial port.
14+
* It waits until the calculated number of bytes have been read and then processes the data.
15+
* 4. The processed image data is rendered on the canvas.
16+
*
317
* @author Sebastian Romero
418
*/
519

@@ -10,14 +24,11 @@ const saveImageButton = document.getElementById('save-image');
1024
const canvas = document.getElementById('bitmapCanvas');
1125
const ctx = canvas.getContext('2d');
1226

13-
// Check the following links for more information on the Web Serial API:
14-
// https://developer.chrome.com/articles/serial/
15-
// https://wicg.github.io/serial/
27+
const imageDataTransfomer = new ImageDataTransformer(ctx);
28+
const connectionHandler = new SerialConnectionHandler();
1629

1730

18-
const imageDataProcessor = new ImageDataProcessor();
19-
let imageDataTransfomer = new ImageDataTransformer();
20-
const connectionHandler = new SerialConnectionHandler();
31+
// Connection handler event listeners
2132

2233
connectionHandler.onConnect = async () => {
2334
connectButton.textContent = 'Disconnect';
@@ -32,46 +43,55 @@ connectionHandler.onConnect = async () => {
3243
console.error(`🚫 Invalid camera configuration: ${cameraConfig[0]}, ${cameraConfig[1]}. Aborting...`);
3344
return;
3445
}
35-
imageDataProcessor.setMode(imageMode);
36-
imageDataProcessor.setResolution(imageResolution.width, imageResolution.height);
3746
imageDataTransfomer.setImageMode(imageMode);
3847
imageDataTransfomer.setResolution(imageResolution.width, imageResolution.height);
39-
connectionHandler.setTransformer(imageDataTransfomer);
4048
renderStream();
4149
};
4250

4351
connectionHandler.onDisconnect = () => {
4452
connectButton.textContent = 'Connect';
45-
imageDataProcessor.reset();
53+
imageDataTransfomer.reset();
4654
};
4755

48-
function renderBitmap(width, height, imageData) {
49-
canvas.width = width;
50-
canvas.height = height;
51-
ctx.clearRect(0, 0, canvas.width, canvas.height);
52-
ctx.putImageData(imageData, 0, 0);
53-
}
56+
57+
// Rendering logic
5458

5559
async function renderStream(){
5660
while(connectionHandler.isConnected()){
57-
if(imageDataProcessor.isConfigured()) await renderFrame();
61+
if(imageDataTransfomer.isConfigured()) await renderFrame();
5862
}
5963
}
6064

65+
/**
66+
* Renders the image data for one frame from the board and renders it.
67+
* @returns {Promise<boolean>} True if a frame was rendered, false otherwise.
68+
*/
6169
async function renderFrame(){
6270
if(!connectionHandler.isConnected()) return;
63-
const bytes = await connectionHandler.getFrame(imageDataProcessor.getTotalBytes());
64-
if(!bytes || bytes.length == 0) return false; // Nothing to render
65-
// console.log(`Reading done ✅. Rendering image...`);
66-
const imageData = ctx.createImageData(320, 240);
67-
const data = imageDataProcessor.getImageData(bytes);
68-
imageData.data.set(data);
69-
70-
renderBitmap(imageDataProcessor.width, imageDataProcessor.height, imageData);
71+
const imageData = await connectionHandler.getFrame(imageDataTransfomer);
72+
if(!imageData) return false; // Nothing to render
73+
if(!(imageData instanceof ImageData)) throw new Error('🚫 Image data is not of type ImageData');
74+
renderBitmap(ctx, imageData);
7175
return true;
7276
}
7377

78+
/**
79+
* Renders the image data on the canvas.
80+
* @param {CanvasRenderingContext2D} context The canvas context to render on.
81+
* @param {ImageData} imageData The image data to render.
82+
*/
83+
function renderBitmap(context, imageData) {
84+
context.canvas.width = imageData.width;
85+
context.canvas.height = imageData.height;
86+
context.clearRect(0, 0, canvas.width, canvas.height);
87+
context.putImageData(imageData, 0, 0);
88+
}
89+
90+
91+
// UI Event listeners
92+
7493
startButton.addEventListener('click', renderStream);
94+
7595
connectButton.addEventListener('click', async () => {
7696
if(connectionHandler.isConnected()){
7797
connectionHandler.disconnectSerial();
@@ -80,8 +100,9 @@ connectButton.addEventListener('click', async () => {
80100
await connectionHandler.connectSerial();
81101
}
82102
});
103+
83104
refreshButton.addEventListener('click', () => {
84-
if(imageDataProcessor.isConfigured()) renderFrame();
105+
if(imageDataTransfomer.isConfigured()) renderFrame();
85106
});
86107

87108
saveImageButton.addEventListener('click', () => {

0 commit comments

Comments
 (0)