brand new javascript frontend with a lot of fancy features!
|
@ -1,51 +0,0 @@
|
|||
/**
|
||||
* Farbtastic Color Picker 1.2
|
||||
* © 2008 Steven Wittens
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
.farbtastic {
|
||||
position: relative;
|
||||
}
|
||||
.farbtastic * {
|
||||
position: absolute;
|
||||
cursor: crosshair;
|
||||
}
|
||||
.farbtastic, .farbtastic .wheel {
|
||||
width: 195px;
|
||||
height: 195px;
|
||||
}
|
||||
.farbtastic .color, .farbtastic .overlay {
|
||||
top: 47px;
|
||||
left: 47px;
|
||||
width: 101px;
|
||||
height: 101px;
|
||||
}
|
||||
.farbtastic .wheel {
|
||||
background: url(../img/wheel.png) no-repeat;
|
||||
width: 195px;
|
||||
height: 195px;
|
||||
}
|
||||
.farbtastic .overlay {
|
||||
background: url(../img/mask.png) no-repeat;
|
||||
}
|
||||
.farbtastic .marker {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
margin: -8px 0 0 -8px;
|
||||
overflow: hidden;
|
||||
background: url(../img/marker.png) no-repeat;
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
width: 295px;
|
||||
text-align: center;
|
||||
margin: 40px auto;
|
||||
}
|
||||
|
||||
#picker {
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
#details {
|
||||
border: 1px solid grey;
|
||||
padding: 3px;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
#details input {
|
||||
border: 1px solid grey;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
#mask input {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
#show_details {
|
||||
font-weight: bold;
|
||||
margin: 30px 0 4px;
|
||||
cursor: pointer;
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
$count = 10;
|
||||
|
||||
$params = array(
|
||||
'color' => (isset($_REQUEST['color'])) ? substr($_REQUEST['color'], 1) : 'ffffff',
|
||||
'delay' => (isset($_REQUEST['delay'])) ? $_REQUEST['delay'] : 0,
|
||||
'step' => (isset($_REQUEST['step'])) ? $_REQUEST['step'] : 255,
|
||||
'mask' => (isset($_REQUEST['mask'])) ? $_REQUEST['mask'] : str_repeat('1', $count),
|
||||
'port' => '/dev/ttyUSB0'
|
||||
);
|
||||
|
||||
$cmd = '../../src/fnctl fade';
|
||||
foreach ($params as $param => $value) {
|
||||
$cmd .= ' --' . $param . '=' . $value;
|
||||
}
|
||||
|
||||
$return;
|
||||
$output = passthru($cmd, $return);
|
||||
|
||||
$json = array(
|
||||
'code' => $return,
|
||||
'output' => $output,
|
||||
'cmd' => $cmd,
|
||||
'params' => $params
|
||||
);
|
||||
|
||||
header('Content-type: application/json');
|
||||
echo json_encode($json);
|
||||
?>
|
Before Width: | Height: | Size: 652 B |
Before Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 12 KiB |
|
@ -1,134 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>fnordlichts</title>
|
||||
<script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/farbtastic.js"></script>
|
||||
<link rel="stylesheet" href="css/farbtastic.css" type="text/css" />
|
||||
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
var locked = false;
|
||||
var count; /* count of lamps */
|
||||
var color; /* last color */
|
||||
|
||||
function stop() {
|
||||
if (!locked) {
|
||||
locked = true;
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'stop',
|
||||
success: function(data) {
|
||||
locked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function start(script) {
|
||||
var mask = get_mask();
|
||||
var data = {
|
||||
script : script
|
||||
};
|
||||
|
||||
if (mask.indexOf('0') != -1) {
|
||||
data.mask = mask;
|
||||
}
|
||||
|
||||
if (!locked) {
|
||||
locked = true;
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'start?' + $.param(data),
|
||||
success: function(data) {
|
||||
locked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function get_mask() {
|
||||
var mask = new String;
|
||||
for (var i=0; i < count; i++) {
|
||||
mask += ($('#lamp_' + i).attr('checked')) ? '1' : '0';
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
function fade(hex) {
|
||||
color = (hex == undefined) ? $.farbtastic('#picker').color.substr(1) : hex.substr(1);
|
||||
|
||||
var mask = get_mask();
|
||||
var data = {
|
||||
color: color,
|
||||
step: $('#step').val(),
|
||||
delay: $('#delay').val(),
|
||||
}
|
||||
|
||||
if (mask.indexOf('0') != -1) {
|
||||
data.mask = mask;
|
||||
}
|
||||
|
||||
if (!locked) {
|
||||
locked = true;
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'fade?' + $.param(data),
|
||||
success: function(data) {
|
||||
locked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
/* draw mask boxes */
|
||||
$.get('count', function(data) {
|
||||
count = parseInt(data);
|
||||
|
||||
for (var i=0; i < count; i++) {
|
||||
$('#mask').append(
|
||||
$('<input>')
|
||||
.attr('type', 'checkbox')
|
||||
.attr('id', 'lamp_' + i)
|
||||
.attr('checked', true)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/* get current color */
|
||||
$.get('color', function(data) {
|
||||
color = data;
|
||||
$.farbtastic('#picker').setColor('#' + color);
|
||||
});
|
||||
|
||||
$('#picker').farbtastic(fade);
|
||||
//$('input').bind('click change keypress', fade);
|
||||
|
||||
$('#details').hide();
|
||||
$('#show_details').click(function() { $('#details').slideToggle(); });
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="picker"></div>
|
||||
<p id="show_details">more..</p>
|
||||
<div id="details">
|
||||
<table>
|
||||
<tr><td><label>Verzögerung</label></td><td><input type="text" id="delay" value="3"/></td></tr>
|
||||
<tr><td><label>Schrittweite</label></td><td><input type="text" id="step" value="20" /></td></tr>
|
||||
<tr><td><label>Lampen</label></td><td><div id="mask" /></td></tr>
|
||||
<tr><td></td><td>
|
||||
<input type="button" onclick="stop()" value="Stop" />
|
||||
<input type="button" onclick="start(1)" value="Party" />
|
||||
<input type="button" onclick="start(0)" value="Farbrad" />
|
||||
</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,345 +0,0 @@
|
|||
/**
|
||||
* Farbtastic Color Picker 1.2
|
||||
* © 2008 Steven Wittens
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
jQuery.fn.farbtastic = function (callback) {
|
||||
$.farbtastic(this, callback);
|
||||
return this;
|
||||
};
|
||||
|
||||
jQuery.farbtastic = function (container, callback) {
|
||||
var container = $(container).get(0);
|
||||
return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
|
||||
}
|
||||
|
||||
jQuery._farbtastic = function (container, callback) {
|
||||
// Store farbtastic object
|
||||
var fb = this;
|
||||
|
||||
// Insert markup
|
||||
$(container).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
|
||||
var e = $('.farbtastic', container);
|
||||
fb.wheel = $('.wheel', container).get(0);
|
||||
// Dimensions
|
||||
fb.radius = 84;
|
||||
fb.square = 100;
|
||||
fb.width = 194;
|
||||
|
||||
// Fix background PNGs in IE6
|
||||
if (navigator.appVersion.match(/MSIE [0-6]\./)) {
|
||||
$('*', e).each(function () {
|
||||
if (this.currentStyle.backgroundImage != 'none') {
|
||||
var image = this.currentStyle.backgroundImage;
|
||||
image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
|
||||
$(this).css({
|
||||
'backgroundImage': 'none',
|
||||
'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Link to the given element(s) or callback.
|
||||
*/
|
||||
fb.linkTo = function (callback) {
|
||||
// Unbind previous nodes
|
||||
if (typeof fb.callback == 'object') {
|
||||
$(fb.callback).unbind('keyup', fb.updateValue);
|
||||
}
|
||||
|
||||
// Reset color
|
||||
fb.color = null;
|
||||
|
||||
// Bind callback or elements
|
||||
if (typeof callback == 'function') {
|
||||
fb.callback = callback;
|
||||
}
|
||||
else if (typeof callback == 'object' || typeof callback == 'string') {
|
||||
fb.callback = $(callback);
|
||||
fb.callback.bind('keyup', fb.updateValue);
|
||||
if (fb.callback.get(0).value) {
|
||||
fb.setColor(fb.callback.get(0).value);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
fb.updateValue = function (event) {
|
||||
if (this.value && this.value != fb.color) {
|
||||
fb.setColor(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change color with HTML syntax #123456
|
||||
*/
|
||||
fb.setColor = function (color) {
|
||||
var unpack = fb.unpack(color);
|
||||
if (fb.color != color && unpack) {
|
||||
fb.color = color;
|
||||
fb.rgb = unpack;
|
||||
fb.hsl = fb.RGBToHSL(fb.rgb);
|
||||
fb.updateDisplay();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change color with HSL triplet [0..1, 0..1, 0..1]
|
||||
*/
|
||||
fb.setHSL = function (hsl) {
|
||||
fb.hsl = hsl;
|
||||
fb.rgb = fb.HSLToRGB(hsl);
|
||||
fb.color = fb.pack(fb.rgb);
|
||||
fb.updateDisplay();
|
||||
return this;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Retrieve the coordinates of the given event relative to the center
|
||||
* of the widget.
|
||||
*/
|
||||
fb.widgetCoords = function (event) {
|
||||
var x, y;
|
||||
var el = event.target || event.srcElement;
|
||||
var reference = fb.wheel;
|
||||
|
||||
if (typeof event.offsetX != 'undefined') {
|
||||
// Use offset coordinates and find common offsetParent
|
||||
var pos = { x: event.offsetX, y: event.offsetY };
|
||||
|
||||
// Send the coordinates upwards through the offsetParent chain.
|
||||
var e = el;
|
||||
while (e) {
|
||||
e.mouseX = pos.x;
|
||||
e.mouseY = pos.y;
|
||||
pos.x += e.offsetLeft;
|
||||
pos.y += e.offsetTop;
|
||||
e = e.offsetParent;
|
||||
}
|
||||
|
||||
// Look for the coordinates starting from the wheel widget.
|
||||
var e = reference;
|
||||
var offset = { x: 0, y: 0 }
|
||||
while (e) {
|
||||
if (typeof e.mouseX != 'undefined') {
|
||||
x = e.mouseX - offset.x;
|
||||
y = e.mouseY - offset.y;
|
||||
break;
|
||||
}
|
||||
offset.x += e.offsetLeft;
|
||||
offset.y += e.offsetTop;
|
||||
e = e.offsetParent;
|
||||
}
|
||||
|
||||
// Reset stored coordinates
|
||||
e = el;
|
||||
while (e) {
|
||||
e.mouseX = undefined;
|
||||
e.mouseY = undefined;
|
||||
e = e.offsetParent;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Use absolute coordinates
|
||||
var pos = fb.absolutePosition(reference);
|
||||
x = (event.pageX || 0*(event.clientX + $('html').get(0).scrollLeft)) - pos.x;
|
||||
y = (event.pageY || 0*(event.clientY + $('html').get(0).scrollTop)) - pos.y;
|
||||
}
|
||||
// Subtract distance to middle
|
||||
return { x: x - fb.width / 2, y: y - fb.width / 2 };
|
||||
}
|
||||
|
||||
/**
|
||||
* Mousedown handler
|
||||
*/
|
||||
fb.mousedown = function (event) {
|
||||
// Capture mouse
|
||||
if (!document.dragging) {
|
||||
$(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
|
||||
document.dragging = true;
|
||||
}
|
||||
|
||||
// Check which area is being dragged
|
||||
var pos = fb.widgetCoords(event);
|
||||
fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
|
||||
|
||||
// Process
|
||||
fb.mousemove(event);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mousemove handler
|
||||
*/
|
||||
fb.mousemove = function (event) {
|
||||
// Get coordinates relative to color picker center
|
||||
var pos = fb.widgetCoords(event);
|
||||
|
||||
// Set new HSL parameters
|
||||
if (fb.circleDrag) {
|
||||
var hue = Math.atan2(pos.x, -pos.y) / 6.28;
|
||||
if (hue < 0) hue += 1;
|
||||
fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
|
||||
}
|
||||
else {
|
||||
var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
|
||||
var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
|
||||
fb.setHSL([fb.hsl[0], sat, lum]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mouseup handler
|
||||
*/
|
||||
fb.mouseup = function () {
|
||||
// Uncapture mouse
|
||||
$(document).unbind('mousemove', fb.mousemove);
|
||||
$(document).unbind('mouseup', fb.mouseup);
|
||||
document.dragging = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the markers and styles
|
||||
*/
|
||||
fb.updateDisplay = function () {
|
||||
// Markers
|
||||
var angle = fb.hsl[0] * 6.28;
|
||||
$('.h-marker', e).css({
|
||||
left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
|
||||
top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
|
||||
});
|
||||
|
||||
$('.sl-marker', e).css({
|
||||
left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
|
||||
top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
|
||||
});
|
||||
|
||||
// Saturation/Luminance gradient
|
||||
$('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
|
||||
|
||||
// Linked elements or callback
|
||||
if (typeof fb.callback == 'object') {
|
||||
// Set background/foreground color
|
||||
$(fb.callback).css({
|
||||
backgroundColor: fb.color,
|
||||
color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
|
||||
});
|
||||
|
||||
// Change linked value
|
||||
$(fb.callback).each(function() {
|
||||
if (this.value && this.value != fb.color) {
|
||||
this.value = fb.color;
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (typeof fb.callback == 'function') {
|
||||
fb.callback.call(fb, fb.color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get absolute position of element
|
||||
*/
|
||||
fb.absolutePosition = function (el) {
|
||||
var r = { x: el.offsetLeft, y: el.offsetTop };
|
||||
// Resolve relative to offsetParent
|
||||
if (el.offsetParent) {
|
||||
var tmp = fb.absolutePosition(el.offsetParent);
|
||||
r.x += tmp.x;
|
||||
r.y += tmp.y;
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
/* Various color utility functions */
|
||||
fb.pack = function (rgb) {
|
||||
var r = Math.round(rgb[0] * 255);
|
||||
var g = Math.round(rgb[1] * 255);
|
||||
var b = Math.round(rgb[2] * 255);
|
||||
return '#' + (r < 16 ? '0' : '') + r.toString(16) +
|
||||
(g < 16 ? '0' : '') + g.toString(16) +
|
||||
(b < 16 ? '0' : '') + b.toString(16);
|
||||
}
|
||||
|
||||
fb.unpack = function (color) {
|
||||
if (color.length == 7) {
|
||||
return [parseInt('0x' + color.substring(1, 3)) / 255,
|
||||
parseInt('0x' + color.substring(3, 5)) / 255,
|
||||
parseInt('0x' + color.substring(5, 7)) / 255];
|
||||
}
|
||||
else if (color.length == 4) {
|
||||
return [parseInt('0x' + color.substring(1, 2)) / 15,
|
||||
parseInt('0x' + color.substring(2, 3)) / 15,
|
||||
parseInt('0x' + color.substring(3, 4)) / 15];
|
||||
}
|
||||
}
|
||||
|
||||
fb.HSLToRGB = function (hsl) {
|
||||
var m1, m2, r, g, b;
|
||||
var h = hsl[0], s = hsl[1], l = hsl[2];
|
||||
m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
|
||||
m1 = l * 2 - m2;
|
||||
return [this.hueToRGB(m1, m2, h+0.33333),
|
||||
this.hueToRGB(m1, m2, h),
|
||||
this.hueToRGB(m1, m2, h-0.33333)];
|
||||
}
|
||||
|
||||
fb.hueToRGB = function (m1, m2, h) {
|
||||
h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
|
||||
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
|
||||
if (h * 2 < 1) return m2;
|
||||
if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
|
||||
return m1;
|
||||
}
|
||||
|
||||
fb.RGBToHSL = function (rgb) {
|
||||
var min, max, delta, h, s, l;
|
||||
var r = rgb[0], g = rgb[1], b = rgb[2];
|
||||
min = Math.min(r, Math.min(g, b));
|
||||
max = Math.max(r, Math.max(g, b));
|
||||
delta = max - min;
|
||||
l = (min + max) / 2;
|
||||
s = 0;
|
||||
if (l > 0 && l < 1) {
|
||||
s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
|
||||
}
|
||||
h = 0;
|
||||
if (delta > 0) {
|
||||
if (max == r && max != g) h += (g - b) / delta;
|
||||
if (max == g && max != b) h += (2 + (b - r) / delta);
|
||||
if (max == b && max != r) h += (4 + (r - g) / delta);
|
||||
h /= 6;
|
||||
}
|
||||
return [h, s, l];
|
||||
}
|
||||
|
||||
// Install mousedown handler (the others are set on the document on-demand)
|
||||
$('*', e).mousedown(fb.mousedown);
|
||||
|
||||
// Init color
|
||||
fb.setColor('#000000');
|
||||
|
||||
// Set linked elements/callback
|
||||
if (callback) {
|
||||
fb.linkTo(callback);
|
||||
}
|
||||
}
|
4
share/web/js/jquery-1.7.1.min.js
vendored
103
web/css/style.css
Normal file
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* fnordlicht web control frontend
|
||||
*
|
||||
* simple ajax colorwheel frontend to control fnordlicht's
|
||||
*
|
||||
* @copyright 2013 Steffen Vogel
|
||||
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
|
||||
* @author Steffen Vogel <post@steffenvogel.de>
|
||||
* @link http://www.steffenvogel.de
|
||||
*/
|
||||
/*
|
||||
* This file is part of libfn
|
||||
*
|
||||
* libfn is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* libfn is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libfn. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
margin: 40px;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#details {
|
||||
padding: 10px;
|
||||
margin: 0 50px;
|
||||
font-size: 0.95em;
|
||||
display: none;
|
||||
text-align: left;
|
||||
|
||||
-moz-border-radius: 15px;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
#details input {
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #727272;
|
||||
padding: 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#details > table {
|
||||
margin: 4px auto;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #727272;
|
||||
}
|
||||
|
||||
#details > p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#details label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
img.icon {
|
||||
margin: 3px 3px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
#show_details {
|
||||
font-weight: bold;
|
||||
color: #C0C0C0;
|
||||
margin: 30px 0 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#wheel {
|
||||
text-align: left;
|
||||
margin: 50px;
|
||||
}
|
||||
|
||||
.alpha60 {
|
||||
/* Fallback for web browsers that doesn't support RGBa */
|
||||
background: rgb(255, 255, 255);
|
||||
|
||||
/* RGBa with 0.6 opacity */
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
|
||||
/* For IE 5.5 - 7*/
|
||||
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99ffffff, endColorstr=#99ffffff);
|
||||
|
||||
/* For IE 8*/
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99ffffff, endColorstr=#99ffffff)";
|
||||
}
|
BIN
web/favicon.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
web/img/bulb-off.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
web/img/bulb-on.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
web/img/lego1.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
BIN
web/img/lego2.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
web/img/lego3.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
web/img/lego4.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
web/img/lego5.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
web/img/lego6.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
45
web/index.html
Normal file
|
@ -0,0 +1,45 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>fnordlichts</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
||||
<link rel="icon" href="favicon.png" type="image/png">
|
||||
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
|
||||
<script type="text/javascript" src="js/raphael-2.1.0.min.js"></script>
|
||||
<script type="text/javascript" src="js/colorwheel.js"></script>
|
||||
<script type="text/javascript" src="js/frontend.js"></script>
|
||||
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="wheel"></div>
|
||||
<p id="show_details">more...</p>
|
||||
<div id="details" class="alpha60">
|
||||
<table>
|
||||
<tr><td><label>Lampen</label></td><td><div id="mask" /></td></tr>
|
||||
<tr><td><label>Benutzer</label></td><td><div id="users" /></td></tr>
|
||||
</table>
|
||||
<table id="options">
|
||||
<tr><td><label>Verzögerung</label></td><td><input type="text" id="delay" value="5" size="3" /> (0-255, in 10ms Schritten)</td></tr>
|
||||
<tr><td><label>Schrittweite</label></td><td><input type="text" id="step" value="8" size="3" maxlength="3" /> (0-255)</td></tr>
|
||||
<tr><td><label>Pause</label></td><td><input type="text" id="sleep" value="10" size="3" maxlength="3" /> (0-255, in 1s Schritten)</td></tr>
|
||||
<tr><td><label>Helligkeit</label></td><td><input type="text" id="value" value="255" size="3" maxlength="3" /> (0-255)</td></tr>
|
||||
<tr><td><label>Sättigung</label></td><td><input type="text" id="saturation" value="255" size="3" maxlength="3" /> (0-255)</td></tr>
|
||||
<tr><td><label>Benutze Adresse</label></td><td><input type="checkbox" id="use_address" checked="checked" /></td></tr>
|
||||
<tr><td><label>Warte auf Fade</label></td><td><input type="checkbox" id="wait_for_fade" value="1" checked="checked" /></td></tr>
|
||||
<tr><td><label>Stoppe vor Fade</label></td><td><input type="checkbox" id="stop_fade" value="1" /></td></tr>
|
||||
</table>
|
||||
<p>
|
||||
<input type="button" onclick="fnFade(Raphael.getRGB('#000000'))" value="Aus" />
|
||||
<input type="button" onclick="fnFade(Raphael.getRGB('#ffffff'))" value="An" />
|
||||
<input type="button" onclick="fnStop()" value="Stop" />
|
||||
<input type="button" onclick="fnStart(1)" value="Party" />
|
||||
<input type="button" onclick="fnStart(0)" value="Farbrad" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
317
web/js/colorwheel.js
Normal file
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* Colorwheel
|
||||
* Copyright (c) 2010 John Weir (http://famedriver.com)
|
||||
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
|
||||
*
|
||||
* requires jQuery & Raphael
|
||||
* http://jquery.com http://raphaeljs.com
|
||||
*
|
||||
* see http://jweir.github.com/colorwheel for Usage
|
||||
*
|
||||
*/
|
||||
|
||||
Raphael.colorwheel = function(target, color_wheel_size, no_segments){
|
||||
var canvas,
|
||||
current_color,
|
||||
size,
|
||||
segments = no_segments || 60,
|
||||
bs_square = {},
|
||||
hue_ring = {},
|
||||
tri_size,
|
||||
cursor = {},
|
||||
drag_target,
|
||||
input_target,
|
||||
center,
|
||||
parent,
|
||||
change_callback,
|
||||
drag_callbacks = [function(){}, function(){}],
|
||||
offset,
|
||||
padding = 2,
|
||||
sdim; // holds the dimensions for the saturation square
|
||||
|
||||
function point(x, y){ return {x:x, y:y};}
|
||||
function radians(a){ return a * (Math.PI/180);}
|
||||
|
||||
function angle(x,y){
|
||||
var q = x > 0 ? 0 : 180;
|
||||
return q+Math.atan((0 - y)/(0 - x))*180/(Math.PI);
|
||||
}
|
||||
|
||||
function create(target, color_wheel_size){
|
||||
size = color_wheel_size;
|
||||
tri_size = size/20;
|
||||
center = size/2;
|
||||
parent = $(target);
|
||||
canvas = Raphael(parent[0],size, size);
|
||||
canvas.safari();
|
||||
|
||||
create_bs_square();
|
||||
create_hue_ring();
|
||||
hue_ring.cursor = cursor_create(tri_size);
|
||||
bs_square.cursor = cursor_create(tri_size*0.5);
|
||||
events_setup();
|
||||
parent.css({height:size+"px", width:size+"px"});
|
||||
disable_select(parent);
|
||||
return public_methods();
|
||||
}
|
||||
|
||||
function disable_select(target){
|
||||
$(target).css({"unselectable": "on","-moz-user-select": "none","-webkit-user-select": "none"});
|
||||
}
|
||||
|
||||
function public_methods(){
|
||||
return {
|
||||
input: input,
|
||||
onchange: onchange,
|
||||
ondrag : ondrag,
|
||||
color : public_set_color
|
||||
};
|
||||
}
|
||||
|
||||
// Sets a textfield for user input of hex color values
|
||||
// TODO don't clear the change callback
|
||||
// TODO allow a null target to unbind the input
|
||||
function input(target){
|
||||
change_callback = null;
|
||||
input_target = target;
|
||||
$(target).keyup(function(){
|
||||
if(this.value.match(/^#([0-9A-F]){3}$|^#([0-9A-F]){6}$/img)){
|
||||
set_color(this.value);
|
||||
update_color(true);
|
||||
run_onchange_event();
|
||||
}
|
||||
});
|
||||
set_color(target.value);
|
||||
update_color(true);
|
||||
|
||||
return public_methods();
|
||||
}
|
||||
|
||||
function onchange(callback){
|
||||
change_callback = callback;
|
||||
update_color(false);
|
||||
return public_methods();
|
||||
}
|
||||
|
||||
function ondrag(start_callback, end_callback){
|
||||
drag_callbacks = [start_callback || function(){}, end_callback || function(){}];
|
||||
return public_methods();
|
||||
}
|
||||
|
||||
function drag(e){
|
||||
var x, y, page;
|
||||
|
||||
e.preventDefault(); // prevents scrolling on touch
|
||||
|
||||
page = e.originalEvent.touches ? e.originalEvent.touches[0] : e;
|
||||
|
||||
x = page.pageX - (parent.offset().left + center);
|
||||
y = page.pageY - (parent.offset().top + center);
|
||||
|
||||
if(drag_target == hue_ring){
|
||||
set_hue_cursor(x,y);
|
||||
update_color();
|
||||
run_onchange_event();
|
||||
return true;
|
||||
}
|
||||
if(drag_target == bs_square){
|
||||
set_bs_cursor(x,y);
|
||||
update_color();
|
||||
run_onchange_event();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function start_drag(event, target){
|
||||
event.preventDefault(); // prevents scrolling on touch
|
||||
|
||||
$(document).on('mouseup touchend',stop_drag);
|
||||
$(document).on('mousemove touchmove',drag);
|
||||
drag_target = target;
|
||||
drag(event);
|
||||
drag_callbacks[0](current_color);
|
||||
}
|
||||
|
||||
function stop_drag(event){
|
||||
event.preventDefault(); // prevents scrolling on touch
|
||||
|
||||
$(document).off("mouseup touchend",stop_drag);
|
||||
$(document).off("mousemove touchmove",drag);
|
||||
drag_callbacks[1](current_color);
|
||||
run_onchange_event();
|
||||
}
|
||||
|
||||
function events_setup(){
|
||||
$([hue_ring.event.node,hue_ring.cursor[0].node]).on("mousedown touchstart",
|
||||
function(e){start_drag(e,hue_ring);});
|
||||
$([bs_square.b.node, bs_square.cursor[0].node]).on("mousedown touchstart",
|
||||
function(e){start_drag(e,bs_square);});
|
||||
}
|
||||
|
||||
function cursor_create(size){
|
||||
var set = canvas.set().push(
|
||||
canvas.circle(0, 0, size).attr({"stroke-width":4, stroke:"#333"}),
|
||||
canvas.circle(0, 0, size+2).attr({"stroke-width":1, stroke:"#FFF", opacity:0.5})
|
||||
);
|
||||
|
||||
set[0].node.style.cursor = "crosshair";
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
function set_bs_cursor(x,y){
|
||||
x = x+center;
|
||||
y = y+center;
|
||||
if(x < sdim.x){x = sdim.x}
|
||||
if(x > sdim.x+sdim.l){x = sdim.x+sdim.l}
|
||||
if(y < sdim.y){y = sdim.y}
|
||||
if(y > sdim.y+sdim.l){y = sdim.y + sdim.l}
|
||||
|
||||
bs_square.cursor.attr({cx:x, cy:y}).transform("t0,0");
|
||||
}
|
||||
|
||||
|
||||
function set_hue(color){
|
||||
var hex = Raphael.getRGB(color).hex;
|
||||
bs_square.h.attr("fill", hex);
|
||||
}
|
||||
|
||||
function hue(){
|
||||
return Raphael.rgb2hsb(bs_square.h.attr("fill")).h;
|
||||
}
|
||||
|
||||
function public_set_color(value){
|
||||
var ret = set_color(value);
|
||||
update_color(false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
function set_color(value){
|
||||
if(value === undefined){ return current_color; }
|
||||
|
||||
var temp = canvas.rect(1,1,1,1).attr({fill:value}),
|
||||
hsb = canvas.raphael.rgb2hsb(temp.attr("fill"));
|
||||
|
||||
set_bs_cursor(
|
||||
(0-sdim.l/2) + (sdim.l*hsb.s),
|
||||
sdim.l/2 - (sdim.l*hsb.b));
|
||||
set_hue_cursor((360*(hsb.h))-90);
|
||||
temp.remove();
|
||||
return public_methods();
|
||||
}
|
||||
|
||||
// Could optimize this method
|
||||
function update_color(dont_replace_input_value){
|
||||
var x = bs_square.cursor.items[0].attr("cx"),
|
||||
y = bs_square.cursor.items[0].attr("cy"),
|
||||
hsb = {
|
||||
b: 1-(y-sdim.y)/sdim.l,
|
||||
s: (x-sdim.x)/sdim.l,
|
||||
h: hue()
|
||||
};
|
||||
|
||||
current_color = Raphael.hsb2rgb(hsb.h, hsb.s,hsb.b);
|
||||
|
||||
if(input_target){
|
||||
var c = current_color.hex;
|
||||
if(dont_replace_input_value !== true) { input_target.value = c;}
|
||||
if(hsb.b < 0.5){
|
||||
$(input_target).css("color", "#FFF");
|
||||
} else {
|
||||
$(input_target).css("color", "#000");
|
||||
}
|
||||
input_target.style.background = c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// accepts either x,y or d (degrees)
|
||||
function set_hue_cursor(mixed_args){
|
||||
var d;
|
||||
if(arguments.length == 2){
|
||||
d = angle(arguments[0],arguments[1]);
|
||||
} else {
|
||||
d = arguments[0];
|
||||
}
|
||||
|
||||
var x = Math.cos(radians(d)) * (center-tri_size-padding);
|
||||
var y = Math.sin(radians(d)) * (center-tri_size-padding);
|
||||
hue_ring.cursor.attr({cx:x+center, cy:y+center}).transform("t0,0");
|
||||
set_hue("hsb("+(d+90)/360+",1,1)");
|
||||
}
|
||||
|
||||
function bs_square_dim(){
|
||||
if(sdim){ return sdim;}
|
||||
var s = size - (tri_size * 4);
|
||||
sdim = {
|
||||
x:(s/6)+tri_size*2+padding,
|
||||
y:(s/6)+tri_size*2+padding,
|
||||
l:(s * 2/3)-padding*2
|
||||
};
|
||||
return sdim;
|
||||
}
|
||||
|
||||
function create_bs_square(){
|
||||
bs_square_dim();
|
||||
box = [sdim.x, sdim.y, sdim.l, sdim.l];
|
||||
|
||||
bs_square.h = canvas.rect.apply(canvas, box).attr({
|
||||
stroke:"#EEE", gradient: "0-#FFF-#000", opacity:1});
|
||||
bs_square.s = canvas.rect.apply(canvas, box).attr({
|
||||
stroke:null, gradient: "0-#FFF-#FFF", opacity:0});
|
||||
bs_square.b = canvas.rect.apply(canvas, box).attr({
|
||||
stroke:null, gradient: "90-#000-#FFF", opacity:0});
|
||||
bs_square.b.node.style.cursor = "crosshair";
|
||||
}
|
||||
|
||||
function hue_segement_shape(){
|
||||
var path = "M -@W 0 L @W 0 L @W @H L -@W @H z";
|
||||
return path.replace(/@H/img, tri_size*2).replace(/@W/img,tri_size);
|
||||
}
|
||||
|
||||
function copy_segment(r, d, k){
|
||||
var n = r.clone();
|
||||
var hue = d*(255/k);
|
||||
|
||||
var s = size/2,
|
||||
t = tri_size,
|
||||
p = padding;
|
||||
|
||||
n.transform("t"+s+","+(s-t)+"r"+(360/k)*d+"t0,-"+(s-t-p)+"");
|
||||
|
||||
n.attr({"stroke-width":0, fill:"hsb("+d*(1/k)+", 1, 0.85)"});
|
||||
hue_ring.hues.push(n);
|
||||
}
|
||||
|
||||
function create_hue_ring(){
|
||||
var s = hue_segement_shape(),
|
||||
tri = canvas.path(s).attr({stroke:"rgba(0,0,0,0)"}).transform("t"+(size/2)+","+padding),
|
||||
k = segments; // # of segments to use to generate the hues
|
||||
|
||||
hue_ring.hues = canvas.set();
|
||||
|
||||
for(n=0; n<k; n++){ copy_segment(tri, n, k); }
|
||||
|
||||
// IE needs a slight opacity to assign events
|
||||
hue_ring.event = canvas.circle(
|
||||
center,
|
||||
center,
|
||||
center-tri_size-padding).attr({"stroke-width":tri_size*2, opacity:0.01});
|
||||
|
||||
hue_ring.outline = canvas.circle(
|
||||
center,
|
||||
center,
|
||||
center-tri_size-padding).attr({"stroke":"#000", "stroke-width":(tri_size*2)+3, opacity:0.1});
|
||||
hue_ring.outline.toBack();
|
||||
hue_ring.event.node.style.cursor = "crosshair";
|
||||
}
|
||||
|
||||
function run_onchange_event(){
|
||||
if (change_callback !== undefined){
|
||||
change_callback(current_color);
|
||||
}
|
||||
}
|
||||
|
||||
return create(target, color_wheel_size);
|
||||
};
|
||||
|
294
web/js/frontend.js
Normal file
|
@ -0,0 +1,294 @@
|
|||
/**
|
||||
* fnordlicht web control frontend
|
||||
*
|
||||
* simple ajax colorwheel frontend to control fnordlicht's
|
||||
*
|
||||
* @copyright 2013 Steffen Vogel
|
||||
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
|
||||
* @author Steffen Vogel <post@steffenvogel.de>
|
||||
* @link http://www.steffenvogel.de
|
||||
*/
|
||||
/*
|
||||
* This file is part of libfn
|
||||
*
|
||||
* libfn is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* libfn is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libfn. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
var wheel; /* the colorwheel object */
|
||||
var state = { };
|
||||
var fade = { step : { } };
|
||||
var seed = Math.random();
|
||||
var listener;
|
||||
|
||||
Math.sgn = function(x) {
|
||||
return (x == 0) ? 0 : (x < 0) ? -1 : 1;
|
||||
}
|
||||
|
||||
function computeFade(current, target, step) {
|
||||
/* search for max distance */
|
||||
var max = 'r';
|
||||
var dist = 0;
|
||||
|
||||
for (var i in target) {
|
||||
if (['r', 'g', 'b'].indexOf(i) == -1) continue;
|
||||
|
||||
var d = Math.abs(target[i] - current[i]);
|
||||
if (d > dist) {
|
||||
max = i;
|
||||
dist = d;
|
||||
}
|
||||
}
|
||||
|
||||
/* adjust fading speeds, relative to max distance */
|
||||
fade.step[max] = Math.sgn(target[max] - current[max]) * step;
|
||||
fade.steps = dist / step;
|
||||
|
||||
for (var i in current) {
|
||||
if (['r', 'g', 'b'].indexOf(i) == -1 || i == max) continue;
|
||||
|
||||
if (dist > 0) {
|
||||
var d = target[i] - current[i];
|
||||
var ratio = d / dist;
|
||||
|
||||
fade.step[i] = ratio * step;
|
||||
}
|
||||
else {
|
||||
fade.step[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function wheelFade(current, target, step, delay) {
|
||||
if (current == target) return;
|
||||
|
||||
window.clearInterval(fade.interval);
|
||||
computeFade(current, target, step, delay);
|
||||
fade.interval = window.setInterval(function() {
|
||||
fade.steps--;
|
||||
|
||||
current.r += fade.step.r;
|
||||
current.g += fade.step.g;
|
||||
current.b += fade.step.b;
|
||||
current.hex = Raphael.rgb(current.r, current.g, current.b);
|
||||
|
||||
if (fade.steps <= 0) {
|
||||
current = target;
|
||||
window.clearInterval(fade.interval);
|
||||
}
|
||||
|
||||
state.color = current;
|
||||
setColor(current);
|
||||
}, delay * 10);
|
||||
}
|
||||
|
||||
function getUrlParams() {
|
||||
var vars = [], hash;
|
||||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
||||
|
||||
for(var i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i].split('=');
|
||||
vars.push(hash[0]);
|
||||
vars[hash[0]] = hash[1];
|
||||
}
|
||||
|
||||
return vars;
|
||||
}
|
||||
|
||||
function fnStop() {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'stop',
|
||||
async: false
|
||||
});
|
||||
}
|
||||
|
||||
function fnStart(script) {
|
||||
var data = {
|
||||
script: script,
|
||||
step: state.step,
|
||||
delay: state.delay,
|
||||
sleep: state.sleep,
|
||||
value: state.value,
|
||||
saturation: state.saturation,
|
||||
use_address: (state.use_address) ? 1 : 0,
|
||||
wait_for_fade: (state.wait_for_fade) ? 1 : 0
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'start?' + $.param(data)
|
||||
});
|
||||
}
|
||||
|
||||
function fnFade(color) {
|
||||
if (fade.running) return;
|
||||
fade.running = true;
|
||||
|
||||
var data = {
|
||||
color: color.hex,
|
||||
step: (fade.drag) ? 255 : state.step,
|
||||
delay: (fade.drag) ? 0 : state.delay
|
||||
};
|
||||
|
||||
if (state.mask.indexOf('0') >= 0) {
|
||||
data.mask = state.mask;
|
||||
}
|
||||
|
||||
if ($('#stop_fade').attr('checked')) {
|
||||
fnStop();
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'fade?' + $.param(data),
|
||||
success: function() {
|
||||
fade.running = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setColor(color) {
|
||||
$(document.body).css('background-color', color.hex);
|
||||
wheel.color(color.hex);
|
||||
}
|
||||
|
||||
function listenCallback(data) {
|
||||
wheelFade(state.color, data.color, data.step, data.delay);
|
||||
|
||||
state.count = data.count;
|
||||
state.users = data.users;
|
||||
|
||||
drawUsers(data.users);
|
||||
|
||||
/* restart listener */
|
||||
listener = $.get('status', { comet: 10 }, listenCallback);
|
||||
}
|
||||
|
||||
function drawLamps(count) {
|
||||
state.mask = new String;
|
||||
|
||||
$('#mask').empty();
|
||||
for (var i = 0; i < count; i++) {
|
||||
$('#mask').append(
|
||||
$('<img>')
|
||||
.addClass('icon').css('cursor', 'pointer')
|
||||
.attr('src', 'img/bulb-on.png').attr('alt', i)
|
||||
.data('index', i)
|
||||
.toggle(function() {
|
||||
$(this).attr('src', 'img/bulb-off.png');
|
||||
var idx = $(this).data('index');
|
||||
state.mask = state.mask.substr(0, idx) + '0' + state.mask.substr(idx+1);
|
||||
}, function() {
|
||||
$(this).attr('src', 'img/bulb-on.png');
|
||||
var idx = $(this).data('index');
|
||||
state.mask = state.mask.substr(0, i) + '1' + state.mask.substr(i+1);
|
||||
})
|
||||
);
|
||||
|
||||
state.mask += '1';
|
||||
}
|
||||
}
|
||||
|
||||
function drawUsers(count) {
|
||||
$('#users').empty();
|
||||
for (var i = 0; i <= count; i++) {
|
||||
$('#users').append(
|
||||
$('<img>')
|
||||
.addClass('icon').attr('alt', i)
|
||||
.attr('src', 'img/lego' + (Math.ceil(seed * 100 + i) % 6 + 1) + '.png')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
/* initialize wheel */
|
||||
wheel = Raphael.colorwheel($('#wheel')[0], 500, 200);
|
||||
wheel.ondrag(function() {
|
||||
fade.dragTimeout = window.setTimeout(function() {
|
||||
fade.drag = true;
|
||||
listener.abort();
|
||||
}, 200);
|
||||
}, function(color) {
|
||||
if (fade.drag) {
|
||||
state.color = color;
|
||||
listener = $.get('status', { comet: 10 }, listenCallback);
|
||||
}
|
||||
else
|
||||
fnFade(color);
|
||||
|
||||
fade.drag = false;
|
||||
window.clearTimeout(fade.dragTimeout);
|
||||
});
|
||||
|
||||
|
||||
wheel.onchange(function(color) {
|
||||
if (fade.drag) {
|
||||
$(document.body).css('background-color', color.hex);
|
||||
fnFade(color);
|
||||
}
|
||||
});
|
||||
|
||||
/* show details */
|
||||
$('#show_details').click(function() {
|
||||
$('#details').toggle();
|
||||
$('#show_details').toggle();
|
||||
});
|
||||
|
||||
$('#options input')
|
||||
.change(function() {
|
||||
var elm = $(this);
|
||||
|
||||
var key = elm.attr('id');
|
||||
var val = elm.val();
|
||||
|
||||
switch (elm.attr('type')) {
|
||||
case 'text':
|
||||
val = parseInt(val);
|
||||
break;
|
||||
case 'checkbox':
|
||||
val = (elm.attr('checked') == 'checked');
|
||||
break;
|
||||
}
|
||||
|
||||
state[key] = val;
|
||||
})
|
||||
.each(function(idx, elm) {
|
||||
$(elm).change();
|
||||
});
|
||||
|
||||
/* start listener for first time*/
|
||||
listener = $.get('status', function(data) {
|
||||
state.color = data.color;
|
||||
setColor(state.color);
|
||||
|
||||
/* draw lamps */
|
||||
drawLamps(data.count);
|
||||
|
||||
/* parse url parameters */
|
||||
window.setTimeout(function() {
|
||||
var params = getUrlParams();
|
||||
if ('party' in params) {
|
||||
fnStart(('script' in params) ? parseInt(params['script']) : 1);
|
||||
}
|
||||
else if ('fade' in params) {
|
||||
if ('step' in params) state.step = parseInt(params['step']);
|
||||
if ('delay' in params) state.delay = parseInt(params['delay']);
|
||||
|
||||
fnFade(Raphael.getRGB(params['fade']));
|
||||
}
|
||||
}, 100);
|
||||
|
||||
listenCallback(data);
|
||||
});
|
||||
});
|