open-organism-observer/setup_microscope.html

442 lines
12 KiB
HTML
Raw Normal View History

<!--- this is the main file --->
<!DOCTYPE html>
<html>
<header>
<link href="bootstrap-5.0.2-dist/css/bootstrap.min.css" rel="stylesheet" ></link>
<script src="bootstrap-5.0.2-dist/js/bootstrap.bundle.min.js" ></script>
2025-01-23 14:18:10 +01:00
<meta charset="utf-8">
<style>
#output{
position: relative;
width: 100%;
}
#video_container{
position: relative;
}
#video {
position:absolute;
z-index: 9;
width: 100%;
}
#canvas-draw{
position:absolute;
z-index:10;
width: 100%;
}
#canvas-debug{
position:absolute;
z-index:10;
width: 20em;
opacity: 100%;
}
#photo {
position:absolute;
z-index:5;
width: 100%;
}
#canvas-temp{
display: none;
}
#control-elements {
height:30em;
}
</style>
</header>
<body>
<div class = "container">
<canvas id="canvas-temp"></canvas>
<!-- the output div is used to display the video, the photo and the canvas where you can draw in (and measure) your organisms. -->
<div id="output" class="row">
<div id = "video_container" class="col-8">
<canvas id="canvas-draw"></canvas>
<img id="photo" alt="The screen capture will appear in this box."></img>
<video autoplay="true" id="video"></video>
</div>
<div class="col-4 ">
<div class = "row">
<button class="btn btn-primary float-end" onclick="takePicture();" id="start-button">
Take photo
</button>
<button class="btn btn-primary float-end" onclick="toggle_cam();">
Toggle camera
</button>
</div>
<div id="control_elements" class="row align-items-end">
<div class="col" name="length" >
<label class = "form-label" for="real_length">
Please enter the length of the object in um:
</label>
<input class="form-control" id = "real_length" type="text"
name="real_length" value=0>
</input>
</div>
</div>
<br>
<form class="needs-validation" id = "microscope_setup">
<div class="row">
<div class="col">
<label class = "form-label" for="name">
Name of Setup
</label>
</div>
<div class="col">
<input class="form-control" type="text" name="name" id = "name"
placeholder="e.g. camera">
</input>
</div>
</div>
<div class="row">
<div class="col">
<label class = "form-label" for="FoV_Width">
Width of Field of View (Camera) [um]
</label>
</div>
<div class="col">
<input class="form-control" type="number" id="FoV_width"
name="FoV_Width">
</input>
</div>
</div>
<div class="row">
<div class="col">
<label class = "form-label" for="FoV_Height">
Height of Field of View (Camera) [um]
</label>
</div>
<div class="col">
<input class="form-control" type="number"
id="FoV_height" name="FoV_Height">
</input>
</div>
</div>
<div class="row">
<div class="col">
<label class = "form-label" for="Slip_Height">
Height of Coverslip [mm]
</label>
</div>
<div class="col">
<input class="form-control" type="number"
id="Slip_height" name="Slip_Height">
</input>
</div>
</div>
<div class="row">
<div class="col">
<label class = "form-label" for="Slip_Width">
Width of Coverslip [mm]
</label>
</div>
<div class="col">
<input class="form-control" type="number"
id="Slip_width" name="Slip_Width">
</input>
</div>
</div>
<div class="row">
<div class="col">
<label class = "form-label" for="eyepiece_number">
Eyepiece Number
</label>
</div>
<div class="col">
<input class="form-control" type="number" id = "Eyepiece_Number" name="eyepiece_number">
</input>
</div>
</div>
<button class="btn btn-primary float-end" type="submit">submit</button>
</form>
</div>
</div>
</div>
</body>
<script>
var db;
let openRequest = indexedDB.open("my_db");
openRequest.onupgradeneeded = function() {
db = openRequest.result;
db.createObjectStore("microscope_setup", {autoIncrement : true});
db.createObjectStore("prep_protocol", {autoIncrement : true});
};
openRequest.onerror = function() {
console.error("Error", openRequest.error);
};
openRequest.onsuccess = function() {
db = openRequest.result;
// continue working with database using db object
};
const form = document.getElementById("microscope_setup");
form.addEventListener("submit", add);
function add(event){
let microscope_setup = {
"name" : document.getElementById("name").value,
"FoV_Height" : document.getElementById("FoV_height").value,
"FoV_Width" : document.getElementById("FoV_width").value,
"Slip_Height" : document.getElementById("Slip_height").value,
"Slip_Width" : document.getElementById("Slip_width").value
}
let transaction = db.transaction(["microscope_setup"], "readwrite");
let objectStore = transaction.objectStore("microscope_setup");
let add_request = objectStore.add(microscope_setup); // (3)
transaction.oncomplete = (event) => {
console.log("All done!");
};
transaction.onerror = (event) => {
console.log("something went wrong");
// Don't forget to handle errors!
};
event.preventDefault();
}
</script>
<script>
var video = document.querySelector("#video");
var out = document.querySelector("#output");
// init video switching get IDs of video inputs
navigator.mediaDevices
.enumerateDevices()
.then((devices) => {
devices.forEach((device) => {
if (device.kind=="videoinput"){
deviceIDs.push(device.deviceId);
}
console.log(`${device.kind}: ${device.label} id = ${device.deviceId}`);
});
})
.catch((err) => {
console.error(`${err.name}: ${err.message}`);
});
// toggle between cameras
var deviceIDs = [];
var device_index = 0;
function toggle_cam(){
device_index += 1
if (device_index>=deviceIDs.length){
device_index=0
};
if (navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: {
deviceId: deviceIDs[device_index],
}, })
.then(function (stream) {
video.srcObject = stream;
})
.catch(function (error) {
console.log("Something went wrong!");
});
}
};
var real_dimensions = document.querySelector("#real_dimensions");
var fov_width = document.querySelector("#FoV_width");
var fov_height = document.querySelector("#FoV_height");
var real_length = document.querySelector("#real_length");
// init drawing
var canvas_draw = document.querySelector("#canvas-draw");
var ctx = canvas_draw.getContext('2d');
var pos = { x: 0, y: 0 };
var start_pos = { x: 0, y: 0 };
// store lines for measurement
var lines = [];
var line = [];
// calculate length of line - helper function
function get_length(line){
var dist = 0.0;
if (line){
for (let j = 0; j < line.length-1; ++j) {
dist += Math.sqrt((line[j].x - line[j+1].x) ** 2 + (line[j].y - line[j+1].y) ** 2);
}
}
//return distance in units
return dist/canvas_draw.width
}
// events to set the position of the drawing cursor
canvas_draw.addEventListener('mousedown', setPosition);
canvas_draw.addEventListener('mouseenter', setPosition);
// set new position from mouse event
// scale canvas coords
function setPosition(e) {
var rect = canvas_draw.getBoundingClientRect();
scaleX = canvas_draw.width / rect.width, // relationship bitmap vs. element for x
scaleY = canvas_draw.height / rect.height;
pos.x = (e.clientX - rect.x) * scaleX;
pos.y = (e.clientY - rect.y) * scaleY;
console.log(pos);
}
// the draw function to draw onto canvas
canvas_draw.addEventListener('mousemove', draw);
function draw(e) {
// mouse left button must be pressed and video must be hidden / a photo must have been taken.
if (e.buttons !== 1 && line.length !== 0) {
// push the line to lines array
console.log('Yay');
line.push({x: pos.x, y: pos.y});
let measured_length = get_length(line);
fov_height.value = ((real_length.value/(measured_length * canvas_draw.width))* canvas_draw.width).toFixed(0);
fov_width.value = ((real_length.value/(measured_length * canvas_draw.width))* canvas_draw.height).toFixed(0);
line = [];
return;
}
// draw on canvas.
if (e.buttons == 1){
canvas_draw.getContext('2d').clearRect(0, 0, canvas_draw.width, canvas_draw.height);
if (lines.length == 1){
draw_path(lines[0]);
}
ctx.beginPath(); // begin
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.strokeStyle = 'black';
// update line
// first time push the first position
if (line.length == 0){
start_pos = {x:pos.x, y:pos.y};
line.push(start_pos);
}
ctx.moveTo(start_pos.x, start_pos.y); // from
setPosition(e);
ctx.lineTo(pos.x, pos.y); // to
ctx.stroke(); // draw it!
}
}
let streaming = false;
function startup() {
output = document.getElementById("output");
video = document.getElementById("video");
canvas = document.getElementById("canvas-temp");
photo = document.getElementById("photo");
startButton = document.getElementById("start-button");
navigator.mediaDevices
.getUserMedia({ video: {width: { ideal: 99999} , height: { ideal: 99999 }}, audio: false })
.then((stream) => {
video.srcObject = stream;
video.play();
})
.catch((err) => {
console.error(`An error occurred: ${err}`);
});
video.addEventListener(
"canplay",
(ev) => {
if (!streaming) {
video_aspect = video.videoWidth / video.videoHeight;
video.style.aspectRatio = video_aspect;
photo.style.aspectRatio = video_aspect;
canvas.style.aspectRatio = video_aspect;
canvas_draw.style.aspectRatio = video_aspect;
canvas_draw.height = canvas_draw.height*5;
canvas_draw.width = canvas_draw.height*video_aspect;
streaming = true;
}
},
false,
);
startButton.addEventListener(
"click",
(ev) => {
takePicture();
ev.preventDefault();
},
false,
);
clearPhoto();
}
// Fill the photo with an indication that none has been
// captured.
function clearPhoto() {
const context = canvas.getContext("2d");
context.fillRect(0, 0, canvas.width, canvas.height);
const data = canvas.toDataURL("image/png");
photo.setAttribute("src", data);
}
// Capture a photo by fetching the current contents of the video
// and drawing it into a canvas, then converting that to a PNG
// format data URL. By drawing it on an offscreen canvas and then
// drawing that to the screen, we can change its size and/or apply
// other changes before drawing it.
function takePicture() {
canvas_draw.getContext('2d').clearRect(0, 0, canvas_draw.width, canvas_draw.height);
const context = canvas.getContext("2d");
if (video.videoWidth && video.videoHeight) {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
video.style.zIndex = 1;
photo.style.zIndex = 5;
canvas.style.zIndex= 10;
const data = canvas.toDataURL("image/png");
photo.setAttribute("src", data);
} else {
clearPhoto();
}
}
// Set up our event listener to run the startup process
// once loading is complete.
window.addEventListener("load", startup, false);
//})();
</script>
</html>