aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--web/js/control.js70
-rw-r--r--web/js/smootCanvas.js94
-rw-r--r--web/smootlight.html110
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&hellip;</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