Skip to content

Commit

Permalink
Merge pull request #87 from owulveryck/eventSender
Browse files Browse the repository at this point in the history
Serving pen and touch events
  • Loading branch information
owulveryck authored Nov 20, 2023
2 parents 762f6ef + d5ec74b commit 1e3250d
Show file tree
Hide file tree
Showing 39 changed files with 1,167 additions and 433 deletions.
76 changes: 17 additions & 59 deletions client/canvasHandling.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
function resizeVisibleCanvas() {
var container = document.getElementById("container");

if (rotate) {
if (portrait) {
var aspectRatio = 1404 / 1872;
} else {
var aspectRatio = 1872 / 1404;
Expand All @@ -14,70 +14,28 @@ function resizeVisibleCanvas() {
var containerAspectRatio = containerWidth / containerHeight;

if (containerAspectRatio > aspectRatio) {
// Canvas is relatively wider than container
//canvas.style.width = '100vw';
//canvas.style.width = '100%';
//canvas.style.height = 'auto';
visibleCanvas.style.width = containerHeight * aspectRatio + "px";
visibleCanvas.style.height = containerHeight + "px";
} else {
// Canvas is relatively taller than container
//canvas.style.width = 'auto';
//canvas.style.height = '100vh';
//canvas.style.height = '100%';
visibleCanvas.style.width = containerWidth + "px";
visibleCanvas.style.height = containerWidth / aspectRatio + "px";
}
renderCanvas(rawCanvas,visibleCanvas);
canvasPresent.style.width = visibleCanvas.style.width;
canvasPresent.style.height = visibleCanvas.style.height;
}
function waiting(message) {
var ctx = visibleCanvas.getContext("2d");
ctx.fillStyle = '#666666';
ctx.fillRect(0, 0, visibleCanvas.width, visibleCanvas.height);

var fontSize = 48;
var fontFamily = "Arial";
var textColor = "red";

// Calculate the text dimensions
ctx.font = fontSize + "px " + fontFamily;
var textWidth = ctx.measureText(message).width;
var textHeight = fontSize;

// Calculate the center position
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;

// Set the fill style and align the text in the center
ctx.fillStyle = textColor;
ctx.textAlign = "center";
ctx.textBaseline = "middle";

// Draw the text at the center
ctx.fillText(message, centerX, centerY);
// Clear the canvas
gl.clearColor(0, 0, 0, 1); // Set clear color (black, in this case)
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// To show the message
messageDiv.textContent = message;
messageDiv.style.display = 'block';
}

function renderCanvas(srcCanvas, dstCanvas) {
let ctxSrc = srcCanvas.getContext('2d');
let ctxDst = dstCanvas.getContext('2d');

let w = srcCanvas.width;
let h = srcCanvas.height;

// Clear the destination canvas
ctxDst.clearRect(0, 0, w, h);
ctxDst.imageSmoothingEnabled = true;


if (rotate) {
// Swap width and height for dstCanvas to accommodate rotated content
dstCanvas.width = h;
dstCanvas.height = w;
ctxDst.translate(0,w); // Move the drawing origin to the right side of dstCanvas
ctxDst.rotate(-Math.PI / 2); // Rotate by 90 degrees


// Since the source canvas is now rotated, width and height are swapped
ctxDst.drawImage(srcCanvas, 0, 0);
} else {
dstCanvas.width = w;
dstCanvas.height = h;
ctxDst.drawImage(srcCanvas, 0, 0);
}

// Reset transformations for future calls
ctxDst.setTransform(1, 0, 0, 1, 0, 0);
}

222 changes: 222 additions & 0 deletions client/glCanvas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
// WebGL initialization
//const gl = visibleCanvas.getContext('webgl');
//const gl = canvas.getContext('webgl', { antialias: true, preserveDrawingBuffer: true });
const gl = canvas.getContext('webgl', { antialias: true });


if (!gl) {
alert('WebGL not supported');
}

// Vertex shader program
const vsSource = `
attribute vec4 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat4 uRotationMatrix;
uniform float uScaleFactor;
varying highp vec2 vTextureCoord;
void main(void) {
gl_Position = uRotationMatrix * vec4(aVertexPosition.xy * uScaleFactor, aVertexPosition.zw);
vTextureCoord = aTextureCoord;
}
`;

// Fragment shader program
const fsSource = `
varying highp vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler, vTextureCoord);
}
`;

function makeRotationZMatrix(angleInDegrees) {
var angleInRadians = angleInDegrees * Math.PI / 180;
var s = Math.sin(angleInRadians);
var c = Math.cos(angleInRadians);

return [
c, -s, 0, 0,
s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
];
}

// Initialize a shader program
function initShaderProgram(gl, vsSource, fsSource) {
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);

const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);

if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram));
return null;
}

return shaderProgram;
}

// Creates a shader of the given type, uploads the source and compiles it.
function loadShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);

if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}

return shader;
}

const shaderProgram = initShaderProgram(gl, vsSource, fsSource);

// Collect all the info needed to use the shader program.
// Look up locations of attributes and uniforms used by our shader
const programInfo = {
program: shaderProgram,
attribLocations: {
vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
textureCoord: gl.getAttribLocation(shaderProgram, 'aTextureCoord'),
},
uniformLocations: {
uSampler: gl.getUniformLocation(shaderProgram, 'uSampler'),
},
};

// Create a buffer for the square's positions.
const positionBuffer = gl.createBuffer();

// Select the positionBuffer as the one to apply buffer operations to from here out.
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

// Now create an array of positions for the square.
const positions = [
1.0, 1.0,
-1.0, 1.0,
1.0, -1.0,
-1.0, -1.0,
];

// Pass the list of positions into WebGL to build the shape.
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

// Set up texture coordinates for the rectangle
const textureCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);

const textureCoordinates = [
// 1.0, 0.0, // Bottom right
// 0.0, 0.0, // Bottom left
// 1.0, 1.0, // Top right
// 0.0, 1.0, // Top left
1.0, 1.0,
0.0, 1.0,
1.0, 0.0,
0.0, 0.0,
];

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);

// Create a texture.
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);


// Set the parameters so we can render any size image.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// To apply a smoothing algorithm, you'll likely want to adjust the texture filtering parameters in your WebGL setup.
// For smoothing, typically gl.LINEAR is used for both gl.TEXTURE_MIN_FILTER and gl.TEXTURE_MAG_FILTER
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

// Upload the image into the texture.
let imageData = new ImageData(width, height);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageData);

// Draw the scene
function drawScene(gl, programInfo, positionBuffer, textureCoordBuffer, texture) {
if (resizeGLCanvas(gl.canvas)) {
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
}
gl.clearColor(0.5, 0.5, 0.5, 0.25); // Gray with 75% transparency
gl.clearDepth(1.0); // Clear everything
gl.enable(gl.DEPTH_TEST); // Enable depth testing
gl.depthFunc(gl.LEQUAL); // Near things obscure far things

// Clear the canvas before we start drawing on it.
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

// Tell WebGL to use our program when drawing
gl.useProgram(programInfo.program);

// Set the shader attributes
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(programInfo.attribLocations.vertexPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);

gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);
gl.vertexAttribPointer(programInfo.attribLocations.textureCoord, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(programInfo.attribLocations.textureCoord);

// Tell WebGL we want to affect texture unit 0
gl.activeTexture(gl.TEXTURE0);

// Bind the texture to texture unit 0
gl.bindTexture(gl.TEXTURE_2D, texture);

// Tell the shader we bound the texture to texture unit 0
gl.uniform1i(programInfo.uniformLocations.uSampler, 0);

gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}

drawScene(gl, programInfo, positionBuffer, textureCoordBuffer, texture);

// Update texture
function updateTexture(newRawData, shouldRotate, scaleFactor) {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, newRawData);

// Set rotation
const uRotationMatrixLocation = gl.getUniformLocation(shaderProgram, 'uRotationMatrix');
const rotationMatrix = shouldRotate ? makeRotationZMatrix(270) : makeRotationZMatrix(0);
gl.uniformMatrix4fv(uRotationMatrixLocation, false, rotationMatrix);

// Set scaling
const uScaleFactorLocation = gl.getUniformLocation(shaderProgram, 'uScaleFactor');
gl.uniform1f(uScaleFactorLocation, scaleFactor);

drawScene(gl, programInfo, positionBuffer, textureCoordBuffer, texture);
}

// Call `updateTexture` with new data whenever you need to update the image

// Let's create a function that resizes the canvas element.
// This function will adjust the canvas's width and height attributes based on its display size, which can be set using CSS or directly in JavaScript.
function resizeGLCanvas(canvas) {
const displayWidth = canvas.clientWidth;
const displayHeight = canvas.clientHeight;

// Check if the canvas size is different from its display size
if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
// Make the canvas the same size as its display size
canvas.width = displayWidth;
canvas.height = displayHeight;
return true; // indicates that the size was changed
}

return false; // indicates no change in size
}
28 changes: 18 additions & 10 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<head>
<title>goMarkableStream</title>
<link rel="icon" type="image/x-icon" href="favicon.ico">
<!-- Including the CSS stylesheet -->
<link rel="stylesheet" href="style.css">
<!-- Including the CSS stylesheet -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="menuContainer">
Expand All @@ -13,28 +13,36 @@
<ul class="menu">
<li><button id="rotate" class="apple-button">Rotate</button></li>
<li><button id="colors" class="apple-button">Colors</button></li>
<!--
<li><button id="startStopButton" class="apple-button">
<div class="icon" id="icon"></div>
<span id="label">Record</span>
</button></li>
<li><button id="startStopButtonWithSound" class="apple-button">
<div class="icon" id="icon2"></div>
<span id="label2">Record with audio</span>
</button></li>
<li><button id="screenshotButton" class="apple-button">Screenshot</button><a id="screenshot"></a></li>
<li><button id="startStopButtonWithSound" class="apple-button">
<div class="icon" id="icon2"></div>
<span id="label2">Record with audio</span>
</button></li>
<li><button id="screenshotButton" class="apple-button">Screenshot</button><a id="screenshot"></a></li>
-->
<li><button id="pointerButton" class="apple-button">Pointer</button></a></li>
<li><button id="switchOrderButton" class="apple-button">Mask drawing</button><a id="switch"></a></li>
</ul>
</div>
</div>
<div id="container">
<canvas id="canvas" width="1872" height="1404"></canvas>
<iframe id="content" allowfullscreen="true" frameborder="0" width="100%" height="100%" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true">></iframe>
<canvas id="canvas"></canvas>
<div id="message" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: red;"> </div>
<canvas id="canvasPresent" width="1872" height="1404"></canvas>
<iframe id="content" allow="camera *;" allowfullscreen="true" frameborder="0" width="100%" height="100%" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true">></iframe>
</div>
<!--<iframe id="content" src="https://docs.google.com/presentation/d/e/2PACX-1vQoU3OkrD499XPCjI1kl18dci2Um6eqCkZlKCMJaCVaUkonu6NOWZkLgDOdpTyJwLJlyZ9Yf8SAMTdE/embed?start=false&loop=false&delayms=3000" frameborder="0" width="100%" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>-->

</body>
<script src="main.js"></script> <!-- Include the JavaScript file -->
<script src="glCanvas.js"></script> <!-- Include the JavaScript file -->
<script src="pointer.js"></script> <!-- Include the JavaScript file -->
<script src="utilities.js"></script> <!-- Include the JavaScript file -->
<script src="recording.js"></script> <!-- Include the JavaScript file -->
<script src="canvasHandling.js"></script> <!-- Include the JavaScript file -->
<script src="uiInteractions.js"></script> <!-- Include the JavaScript file -->
<script src="workersHandling.js"></script>
</html>
Loading

0 comments on commit 1e3250d

Please sign in to comment.