diff --git a/openflexure_microscope/api/static/main_v1.js b/openflexure_microscope/api/static/main_v1.js new file mode 100644 index 00000000..5d3f02b2 --- /dev/null +++ b/openflexure_microscope/api/static/main_v1.js @@ -0,0 +1,190 @@ +// TODO: Remember a position and restore that position +// TODO: Right click to auto-focus, centered on that region + +var baseURI = "/api/v1" + +// Key IDs +var pgupKeyID = 33; +var pgdnKeyID = 34; + +var leftKeyID = 37; +var upKeyID = 38; +var rightKeyID = 39; +var downKeyID = 40; + +var enterKeyID = 13; +var escKeyID = 27; + +var keysDown = {}; //Array of keys down + +var stageVelocity = 50; +var focusVelocity = 20; + +var requestLock = false; + +// Microscope client-side callibration +//TODO: Move to serverside microscope property +var fovX = 4100; +var fovY = 3146; + +window.onload = function() { + getStagePositions() +} + +function updateTextBoxes() { + document.getElementById('stageVelocityText').value = stageVelocity; + document.getElementById('focusVelocityText').value = focusVelocity; + + document.getElementById('fovXText').value = fovX; + document.getElementById('fovYText').value = fovY; +} + +function updateStagePositions(response) { + document.getElementById('x_abs').value = response["x"]; + document.getElementById('y_abs').value = response["y"]; + document.getElementById('z_abs').value = response["z"]; +} + +function getStagePositions() { + function updatePositionCallback(response, status) { + console.log(status, response); + updateStagePositions(response); + } + safeRequest("GET", baseURI+"/position", null, updatePositionCallback) +} + +function setStagePositions(x_abs, y_abs, z_abs) { + // Make a position request + function absMoveCallback(response, status) { + if (status == 400) { + alert("Stage cannot be moved further than the safe range."); + } + console.log(status, response); + updateStagePositions(response); + } + safeRequest("POST", baseURI+"/position", { "absolute": true, "x": x_abs, "y": y_abs, "z": z_abs}, absMoveCallback) +} + +function moveStagePositions(x_rel, y_rel, z_rel) { + // Make a position request + function relMoveCallback(response, status) { + if (status == 400) { + alert("Stage cannot be moved further than the safe range."); + } + console.log(status, response); + updateStagePositions(response); + } + safeRequest("POST", baseURI+"/position", { "absolute": false, "x": x_rel, "y": y_rel, "z": z_rel}, relMoveCallback) +} + +function setStagePositionsFromInput() { + x_abs = Number(document.getElementById('x_abs').value); + y_abs = Number(document.getElementById('y_abs').value); + z_abs = Number(document.getElementById('z_abs').value); + setStagePositions(x_abs, y_abs, z_abs) +} + +// Standard callback for user-controller movement +function keyMoveCallback(response, status) { + console.log(status, response); + updateStagePositions(response); +} + +// Methods for input events + +// Click-to-move +function clickHotspotImage(event) { + if (document.getElementById("clickPositionCheck").checked == true) { + xCoordinate = event.offsetX; + yCoordinate = event.offsetY; + console.log(xCoordinate, yCoordinate) + xRelative = (0.5*event.target.offsetWidth - xCoordinate)/event.target.offsetWidth; + yRelative = (0.5*event.target.offsetHeight - yCoordinate)/event.target.offsetHeight; + console.log(xRelative, yRelative) + xSteps = xRelative * fovX; + ySteps = yRelative * fovY; + console.log(xSteps, ySteps, 0) + // Make a position request + moveStagePositions(xSteps, ySteps, 0) + } +} + +// Scroll-to-focus +window.addEventListener('wheel', function(e) { + multiplier = 1/100; + z_delta = e.deltaY * multiplier * focusVelocity; + if (document.getElementById("scrollFocusCheck").checked == true) { + console.log(z_delta); + // Make a position request + safeRequest("POST", baseURI+"/position", { "absolute": false, "z": z_delta}, keyMoveCallback) + } +}); + +// Keyboard to move +addEventListener("keydown", function (e) { + keysDown[e.keyCode] = true; //Add key to array + console.log(keysDown) + + // If stage movement keys are pressed + if ((leftKeyID in keysDown) || (rightKeyID in keysDown) || (upKeyID in keysDown) || (downKeyID in keysDown) || (pgupKeyID in keysDown) || (pgdnKeyID in keysDown)) { + // Calculate movement array + x_rel = 0; + y_rel = 0; + z_rel = 0; + if (leftKeyID in keysDown) { + x_rel = x_rel + stageVelocity; + } + if (rightKeyID in keysDown) { + x_rel = x_rel - stageVelocity; + } + if (upKeyID in keysDown) { + y_rel = y_rel + stageVelocity; + } + if (downKeyID in keysDown) { + y_rel = y_rel - stageVelocity; + } + if (pgupKeyID in keysDown) { + z_rel = z_rel - focusVelocity; + } + if (pgdnKeyID in keysDown) { + z_rel = z_rel + focusVelocity; + } + + // Make a position request + moveStagePositions(x_rel, y_rel, z_rel) + } + +}, false); + +addEventListener("keyup", function (e) { + delete keysDown[e.keyCode]; //Remove key from array +}, false); + +// Methods for making requests +function safeRequest(method, url, payload, callback) { + if (requestLock == false) { + var xhr = new XMLHttpRequest(); // new HttpRequest instance + xhr.open(method, url); + requestLock = true; + + xhr.onload = function (e) { + if (xhr.readyState === 4) { + if (xhr.status !== 200) { + console.error(xhr.statusText); + } + callback(JSON.parse(xhr.responseText), xhr.status); + } + requestLock = false; + }; + + if (method == "POST" || method == "PUT") { + xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); + } + + xhr.send(JSON.stringify(payload)); + + } + else { + console.log("Cannot start new request while previous requets is pending...") + } +} diff --git a/openflexure_microscope/api/static/style_v1.css b/openflexure_microscope/api/static/style_v1.css new file mode 100644 index 00000000..f45a03d6 --- /dev/null +++ b/openflexure_microscope/api/static/style_v1.css @@ -0,0 +1,65 @@ +body { + margin: 0; + overflow: hidden; + font-family: sans-serif; + font-size: 14px; +} + +* { + box-sizing: border-box; +} + +/* Preview sizing */ +img { + width: 100%; + height: 100%; + object-fit: contain +} + +/* Create columns that float next to each other */ +.column { + padding: 10px; + height: 100%; +} + +.left, .right { + background-color: #f4f4f4; +} + +.left{ + width: 250px; + float: left; +} + +.Right{ + width: 250px; + float: right; +} + +.middle { + margin-left: 250px; + margin-right: 250px; + background-color: #d3d3d3; +} + +/* Clear floats after the columns */ +.row:after { + content: ""; + display: table; + clear: both; +} + +/* Columns within panels */ + +.left-col { + float:left; +} +.right-col { + float:right; +} +.clearfix::after { + content: ""; + clear: both; + display: table; +} + diff --git a/openflexure_microscope/api/templates/index_v1.html b/openflexure_microscope/api/templates/index_v1.html index ae0b4d3f..1dd35927 100644 --- a/openflexure_microscope/api/templates/index_v1.html +++ b/openflexure_microscope/api/templates/index_v1.html @@ -1,218 +1,87 @@
+ x:
+ y:
+ z:
+
+ + +
- Scroll focus: -
+ Doubleclick to position:
+
+ Up/down/left/right:
+ Move stage in x-y.
+ PgUp/PgDn:
+ Move stage in z/focus.
+
Scroll to focus:
+ +Not yet implemented.
+