Loading openflexure_microscope/api/static/main_v1.js 0 → 100644 +190 −0 Original line number Diff line number Diff line // 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...") } } openflexure_microscope/api/static/style_v1.css 0 → 100644 +65 −0 Original line number Diff line number Diff line 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; } openflexure_microscope/api/templates/index_v1.html +77 −208 Original line number Diff line number Diff line <html> <head> <title>OpenFlexure Microscope API Demo</title> <link rel= "stylesheet" type= "text/css" href="{{url_for('static', filename='style_v1.css')}}"> <script type="text/javascript" src="{{url_for('static', filename='main_v1.js')}}"></script> </head> <body> <h1>OpenFlexure Microscope API Demo</h1> <img src="{{ url_for('stream') }}" ondblclick="clickHotspotImage(event)";> <br> x: <input type="number" id="x_abs"> y: <input type="number" id="y_abs"> z: <input type="number" id="z_abs"> <div class="row"> <div class="column left"> <h2>Settings</h2> <h3>Position</h3> <p> x: <input type="number" id="x_abs"><br> y: <input type="number" id="y_abs"><br> z: <input type="number" id="z_abs"><br> </p> <p> <button type="button" onclick="setStagePositionsFromInput();">GO</button> <button type="button" onclick="getStagePositions();">Update</button> <br> Velocity: <br> x-y: <input type="range" name="stageVelocityInput" min="50" max="200" value="100" oninput="stageVelocity = Number(this.value);"> </p> <p> Doubleclick to position: <input type="checkbox" id="clickPositionCheck" checked><br> <div class="clearfix"> <div class="left-col">FOV width:</div> <div class="right-col"> <input type="text" id="fovXText" value="4100" size="4" onchange="fovX = Number(this.value); updateTextBoxes();"> </div> </div> <div class="clearfix"> <div class="left-col">FOV height:</div> <div class="right-col"> <input type="text" id="fovYText" value="3146" size="4" onchange="fovY = Number(this.value); updateTextBoxes();"> </div> </div> </p> <h3>Move</h3> <p> <b>Up/down/left/right:</b> <br> Move stage in x-y. <br> <b>PgUp/PgDn: </b> <br> Move stage in z/focus. </p> <h4>Velocity:</h4> <div class="clearfix"> <div class="left-col">x-y:</div> <div class="right-col"> <input type="range" name="stageVelocityInput" min="50" max="200" value="100" oninput="stageVelocity = Number(this.value); updateTextBoxes();"> <input type="text" id="stageVelocityText" value="100" size="3" disabled> z: <input type="range" name="focusVelocityInput" min="10" max="100" value="20" oninput="focusVelocity = Number(this.value);"> </div> </div> <div class="clearfix"> <div class="left-col">z:</div> <div class="right-col"> <input type="range" name="focusVelocityInput" min="10" max="100" value="20" oninput="focusVelocity = Number(this.value); updateTextBoxes();"> <input type="text" id="focusVelocityText" value="20" size="3" disabled> <br> </div> </div> Scroll focus: <input type="checkbox" id="scrollFocusCheck" checked> <br> Click position: <input type="checkbox" id="clickPositionCheck" checked> x FOV: <input type="text" id="fovXText" value="4100" size="4" onchange="fovX = Number(this.value);"> y FOV: <input type="text" id="fovYText" value="3146" size="4" onchange="fovY = Number(this.value);"> <p>Scroll to focus: <input type="checkbox" id="scrollFocusCheck" checked></p> </div> <div class="column right"> <h2>Captures</h2> <p>Not yet implemented.</p> </div> </body> <div class="column middle"> <img src="/api/v1/stream" ondblclick="clickHotspotImage(event)" ;="" style="width: 100%;"> </div> </div> <script> // TODO: Remember a position and restore that position // TODO: Right click to auto-focus, centered on that region // 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 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", "{{ url_for('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", "{{ url_for('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", "{{ url_for('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) moveStagePositions(xSteps, ySteps, 0) } } // Scroll-to-focus window.addEventListener('wheel', function(e) { multiplier = 1/100; z_delta = e.deltaY * multiplier * focusVelocity; console.log(z_delta); if (document.getElementById("scrollFocusCheck").checked == true) { // Make a position request safeRequest("POST", "{{ url_for('position') }}", { "absolute": false, "z": z_delta}, keyMoveCallback) } }); 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...") } } </script> </body> </html> Loading
openflexure_microscope/api/static/main_v1.js 0 → 100644 +190 −0 Original line number Diff line number Diff line // 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...") } }
openflexure_microscope/api/static/style_v1.css 0 → 100644 +65 −0 Original line number Diff line number Diff line 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; }
openflexure_microscope/api/templates/index_v1.html +77 −208 Original line number Diff line number Diff line <html> <head> <title>OpenFlexure Microscope API Demo</title> <link rel= "stylesheet" type= "text/css" href="{{url_for('static', filename='style_v1.css')}}"> <script type="text/javascript" src="{{url_for('static', filename='main_v1.js')}}"></script> </head> <body> <h1>OpenFlexure Microscope API Demo</h1> <img src="{{ url_for('stream') }}" ondblclick="clickHotspotImage(event)";> <br> x: <input type="number" id="x_abs"> y: <input type="number" id="y_abs"> z: <input type="number" id="z_abs"> <div class="row"> <div class="column left"> <h2>Settings</h2> <h3>Position</h3> <p> x: <input type="number" id="x_abs"><br> y: <input type="number" id="y_abs"><br> z: <input type="number" id="z_abs"><br> </p> <p> <button type="button" onclick="setStagePositionsFromInput();">GO</button> <button type="button" onclick="getStagePositions();">Update</button> <br> Velocity: <br> x-y: <input type="range" name="stageVelocityInput" min="50" max="200" value="100" oninput="stageVelocity = Number(this.value);"> </p> <p> Doubleclick to position: <input type="checkbox" id="clickPositionCheck" checked><br> <div class="clearfix"> <div class="left-col">FOV width:</div> <div class="right-col"> <input type="text" id="fovXText" value="4100" size="4" onchange="fovX = Number(this.value); updateTextBoxes();"> </div> </div> <div class="clearfix"> <div class="left-col">FOV height:</div> <div class="right-col"> <input type="text" id="fovYText" value="3146" size="4" onchange="fovY = Number(this.value); updateTextBoxes();"> </div> </div> </p> <h3>Move</h3> <p> <b>Up/down/left/right:</b> <br> Move stage in x-y. <br> <b>PgUp/PgDn: </b> <br> Move stage in z/focus. </p> <h4>Velocity:</h4> <div class="clearfix"> <div class="left-col">x-y:</div> <div class="right-col"> <input type="range" name="stageVelocityInput" min="50" max="200" value="100" oninput="stageVelocity = Number(this.value); updateTextBoxes();"> <input type="text" id="stageVelocityText" value="100" size="3" disabled> z: <input type="range" name="focusVelocityInput" min="10" max="100" value="20" oninput="focusVelocity = Number(this.value);"> </div> </div> <div class="clearfix"> <div class="left-col">z:</div> <div class="right-col"> <input type="range" name="focusVelocityInput" min="10" max="100" value="20" oninput="focusVelocity = Number(this.value); updateTextBoxes();"> <input type="text" id="focusVelocityText" value="20" size="3" disabled> <br> </div> </div> Scroll focus: <input type="checkbox" id="scrollFocusCheck" checked> <br> Click position: <input type="checkbox" id="clickPositionCheck" checked> x FOV: <input type="text" id="fovXText" value="4100" size="4" onchange="fovX = Number(this.value);"> y FOV: <input type="text" id="fovYText" value="3146" size="4" onchange="fovY = Number(this.value);"> <p>Scroll to focus: <input type="checkbox" id="scrollFocusCheck" checked></p> </div> <div class="column right"> <h2>Captures</h2> <p>Not yet implemented.</p> </div> </body> <div class="column middle"> <img src="/api/v1/stream" ondblclick="clickHotspotImage(event)" ;="" style="width: 100%;"> </div> </div> <script> // TODO: Remember a position and restore that position // TODO: Right click to auto-focus, centered on that region // 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 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", "{{ url_for('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", "{{ url_for('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", "{{ url_for('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) moveStagePositions(xSteps, ySteps, 0) } } // Scroll-to-focus window.addEventListener('wheel', function(e) { multiplier = 1/100; z_delta = e.deltaY * multiplier * focusVelocity; console.log(z_delta); if (document.getElementById("scrollFocusCheck").checked == true) { // Make a position request safeRequest("POST", "{{ url_for('position') }}", { "absolute": false, "z": z_delta}, keyMoveCallback) } }); 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...") } } </script> </body> </html>