diff options
-rw-r--r-- | web/js/control.js | 70 | ||||
-rw-r--r-- | web/js/smootCanvas.js | 94 | ||||
-rw-r--r-- | web/smootlight.html | 110 |
3 files changed, 180 insertions, 94 deletions
diff --git a/web/js/control.js b/web/js/control.js new file mode 100644 index 0000000..8fce419 --- /dev/null +++ b/web/js/control.js @@ -0,0 +1,70 @@ +/* control.js - control the SmootLight installation + * + * Copyright (C) 2011 by Benjamin Barenblat + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * The script talks with the installation by making HTTP requests to the given + * URL. + */ +const installationEntryPointURL = "lights.json" + +/** + * Reloads the behavior list, updating the control form accordingly. + */ +function refreshBehaviorList() { + const request = { "OperationType": "ListAll", + "Key": "Behaviors" }; + $.getJSON(installationEntryPointURL, + request, + function(behaviors) { + setBehaviors(behaviors); + showRefreshButton(); + }); +} + +/** + * Sets the behavior list in the control form. + * + * @param behaviors Array of behavior objects to set. Each object must have a + * name field, which will be displayed as the behavior's name. + */ +function setBehaviors(behaviors) { + $("#behaviors option").remove() + for (var i = 0; i < behaviors.length; i++) { + $("#behaviors").append("<option value=\"" + + behaviors[i].name + + "\">" + + behaviors[i].name + + "</option>"); + } +} + +function showRefreshButton() { + $("#preferences #refreshBehaviorListButton").removeClass("invisible"); +} + +// Refresh the behavior list as soon as the DOM is available. +$(refreshBehaviorList); diff --git a/web/js/smootCanvas.js b/web/js/smootCanvas.js new file mode 100644 index 0000000..9b7121c --- /dev/null +++ b/web/js/smootCanvas.js @@ -0,0 +1,94 @@ +var websocket_address = "ws://localhost:8000"; +var circular_pixels = true; /* False for square */ + +var canvas; +var ctx; +var ws; + +var frameCount; +var lastTime; + +window.onload = function() { + canvas = document.getElementById('canvas'); + ctx = canvas.getContext('2d'); + blank(); + + frameCount = 0; + lastTime = (new Date).getTime(); + + connect(); +}; + +function connect() { + ws = new WebSocket(websocket_address); + + ws.onopen = function() { + document.getElementById('connection').innerHTML = 'Status: connected'; + } + + ws.onmessage = function(e) { + var data = JSON.parse(e.data); + + if (data['status'] == 'ok') { + blank(); + var size = data['size']; + var frame = data['frame']; + + var xo = size[0]; + var xf = canvas.width / (size[2]-size[0]); + var yo = size[1]; + var yf = canvas.height / (size[3]-size[1]); + + var pixelWidth = xf; + var pixelHeight = yf; + var pixelRadius = Math.min(xf, yf) / 2.0; + + for (var i = 0; i < frame.length; i++) { + var pos = frame[i][0]; + var clr = frame[i][1]; + + var x = (pos[0] - xo) * xf; + var y = (pos[1] - yo) * yf; + + ctx.fillStyle = clr; + ctx.strokeStyle = clr; + + if (circular_pixels) { + ctx.beginPath(); + ctx.arc(x, y, pixelRadius, 0, Math.PI*2, true); + ctx.closePath(); + ctx.fill(); + } else { + ctx.fillRect(x, y, pixelWidth, pixelHeight); + } + } + + if (frameCount == 30) { + frameCount = 0; + var t = (new Date).getTime(); + var dt = t - lastTime; + var fr = 30 / (dt / 1000.0); + document.getElementById('framerate').innerHTML = 'Framerate: ' + fr.toFixed(2) + ' fps'; + + lastTime = t; + } + + frameCount += 1; + + } else if (data['status'] == 'exiting') { + document.getElementById('framerate').innerHTML = ''; + ws.close(); + } + }; + + ws.onclose = function() { + document.getElementById('connection').innerHTML = 'Status: disconnected'; + blank(); + setTimeout(connect, 2000); + } +} + +function blank() { + ctx.fillStyle = 'rgb(0,0,0)'; + ctx.fillRect(0, 0, canvas.width, canvas.height); +} diff --git a/web/smootlight.html b/web/smootlight.html index 5b64a28..ff50964 100644 --- a/web/smootlight.html +++ b/web/smootlight.html @@ -1,107 +1,29 @@ <!DOCTYPE html> <head> <title>SmootLight</title> -<script> -var websocket_address = "ws://localhost:8000"; -var circular_pixels = true; /* False for square */ - -var canvas; -var ctx; -var ws; +<script type='text/javascript' src='js/smootCanvas.js'></script> +<script type='text/javascript' src='http://code.jquery.com/jquery-1.5.min.js'></script> +<script type='text/javascript' src='js/control.js'></script> -var frameCount; -var lastTime; - -window.onload = function() { - canvas = document.getElementById('canvas'); - ctx = canvas.getContext('2d'); - blank(); - - frameCount = 0; - lastTime = (new Date).getTime(); - - connect(); -}; - -function connect() { - ws = new WebSocket(websocket_address); - - ws.onopen = function() { - document.getElementById('connection').innerHTML = 'Status: connected'; - } - - ws.onmessage = function(e) { - var data = JSON.parse(e.data); - - if (data['status'] == 'ok') { - blank(); - var size = data['size']; - var frame = data['frame']; - - var xo = size[0]; - var xf = canvas.width / (size[2]-size[0]); - var yo = size[1]; - var yf = canvas.height / (size[3]-size[1]); - - var pixelWidth = xf; - var pixelHeight = yf; - var pixelRadius = Math.min(xf, yf) / 2.0; - - for (var i = 0; i < frame.length; i++) { - var pos = frame[i][0]; - var clr = frame[i][1]; - - var x = (pos[0] - xo) * xf; - var y = (pos[1] - yo) * yf; - - ctx.fillStyle = clr; - ctx.strokeStyle = clr; - - if (circular_pixels) { - ctx.beginPath(); - ctx.arc(x, y, pixelRadius, 0, Math.PI*2, true); - ctx.closePath(); - ctx.fill(); - } else { - ctx.fillRect(x, y, pixelWidth, pixelHeight); - } - } - - if (frameCount == 30) { - frameCount = 0; - var t = (new Date).getTime(); - var dt = t - lastTime; - var fr = 30 / (dt / 1000.0); - document.getElementById('framerate').innerHTML = 'Framerate: ' + fr.toFixed(2) + ' fps'; - - lastTime = t; - } - - frameCount += 1; - - } else if (data['status'] == 'exiting') { - document.getElementById('framerate').innerHTML = ''; - ws.close(); - } - }; - - ws.onclose = function() { - document.getElementById('connection').innerHTML = 'Status: disconnected'; - blank(); - setTimeout(connect, 2000); +<style type='text/css'> + .invisible { + display: none; } -} - -function blank() { - ctx.fillStyle = 'rgb(0,0,0)'; - ctx.fillRect(0, 0, canvas.width, canvas.height); -} -</script> +</style> </head> <body> <canvas id='canvas' style='margin: 50px 25px;' width='800px' height='500px'></canvas> <div id='connection'></div> <div id='framerate'></div> + + <div id='control'> + <form id='preferences' action='#'> + <select id='behaviors'> + <option>Loading behaviors…</option> + </select> + <input id='refreshBehaviorListButton' type='button' value='Refresh behavior list' onclick='refreshBehaviorList()' class='invisible' /> + </form> + </div> </body> </html>
\ No newline at end of file |