UNPKG

dmx-web

Version:

DMX webservice and web ui powered by node-dmx

257 lines (238 loc) 7.27 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>DMX Lichtschalter</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="apple-mobile-web-app-capable" content="yes" /> <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet"> <style> body { background: #222; color: #eee; } h1 { clear: both; } input[type=range] { -webkit-appearance: slider-vertical; height: 100px; width: 60px; margin-bottom: 2em; margin-top: 3em; } input[type=range]:before { content: attr(value); color: #eee; font-family: monospace; text-align: center; width: 60px; display: block; color: #fff; position: absolute; top: 2em; } .device { clear: both; padding-top: 1em; } .channel { position: relative; text-align: center; float: left; } .btn { margin-bottom: 1em; } </style> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script> <script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> function get_html_id(universe, channel) { return 'channel_' + universe + '_' + channel; } function rgb_to_array(str) { matches = str.match(/^#([0-9a-f]{6})$/i) if (!matches) { return [0,0,0] } m = matches[1]; if(m) { return [ parseInt(m.substr(0,2),16), parseInt(m.substr(2,2),16), parseInt(m.substr(4,2),16) ]; } } function decimalToHex(d, padding) { var hex = Number(d).toString(16); padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding; while (hex.length < padding) { hex = "0" + hex; } return hex; } function array_to_rgb(arr) { return '#'+decimalToHex(arr[0])+decimalToHex(arr[1])+decimalToHex(arr[2]); } var socket = io(); socket.on('init', function (msg) { $('#presets').empty(); $('#sliders').empty(); $('#anim').empty(); setup = msg.setup devices = msg.devices if(setup.title !== undefined) { document.title = setup.title; } /* preset buttons */ for(var preset in setup.presets) { var html = '<button class="span2 btn btn-info">' + setup.presets[preset].label + '</button>'; var e = $(html) e.hide().appendTo('#presets').fadeIn(); e.click(function(values) { return function() { for(var universe in values) { socket.emit('update', universe, values[universe]); } };}(setup.presets[preset].values)); } /* blackout button */ var blackout = $('<button class="span2 btn btn-danger">Black Out</button>'); blackout.hide().appendTo('#presets').fadeIn(); blackout.click(function() { for(var universe in setup.universes) { var u = {}; for(var i = 0; i < 255; i++) { u[i] = 0; } socket.emit('update', universe, u); } }); /* sliders */ for(var universe in setup.universes) { var html = "<div><h1>" + universe + "</h1>"; for(var device in setup.universes[universe].devices) { var dev = setup.universes[universe].devices[device]; html += '<div class="device">'; if(dev.name !== undefined) { html += '<h4 class="name">'+dev.name+'</h4>' } for(var channel in devices[dev.type].channels) { var channel_id = dev.address + Number(channel) var html_id = get_html_id(universe, channel_id); html += '<div class="channel">' html += '<label for="' + html_id + '">' + devices[dev.type].channels[channel] + '</label>'; html += '<input id="' + html_id + '" type="range" min="0" value="0" max="255" orient="vertical">' html += '</div>' } if(devices[dev.type].channels.includes('red') && devices[dev.type].channels.includes('blue') && devices[dev.type].channels.includes('green')) { var html_id = get_html_id(universe, dev.address); html += '<input id="picker_'+html_id+'" type="color" data-red="'+devices[dev.type].channels.indexOf('red'); html += '" data-green="'+devices[dev.type].channels.indexOf('green')+'" data-blue="'+devices[dev.type].channels.indexOf('blue')+'"/>'; } html += '</div>' } html += "</div>"; $(html).hide().appendTo('#sliders').fadeIn(); } /* animations */ for(var animation in setup.animPresets) { var html = '<button class="span2 btn btn-info">' + setup.animPresets[animation].label + '</button>'; var e = $(html) e.hide().appendTo('#anim').fadeIn(); e.click(function(values) { return function() { for(var universe in values) { $.ajax({ type: 'POST', contentType: 'application/json', data: JSON.stringify(values[universe]), url: '/animation/'+universe, processData: false, dataType: 'json' }); } };}(setup.animPresets[animation].anim)); } $("input").live("change", function(e) { var i = e.target.id.split('_'); if(i[0] === 'picker') { var u = {}; var tar = $(e.target); var value = rgb_to_array(tar.val()); u[Number(i[3])+Number(tar.data('red'))] = value[0]; u[Number(i[3])+Number(tar.data('green'))] = value[1]; u[Number(i[3])+Number(tar.data('blue'))] = value[2]; socket.emit('update', i[2], u); } else { var u = {}; u[i[2]] = e.target.value; socket.emit('update', i[1], u); } }); socket.emit('request_refresh'); }); socket.on('update', function (universe, update) { for(var k in update) { $('#' + get_html_id(universe, k)).attr('value', update[k]); } $("[id^=picker_channel_"+universe+"]").each(function(index, value){ var self = $(this); var id = self.attr('id').split('_'); var obj = self.data(); var arr = Object.keys(obj).map(function(key){return obj[key];}); var _id = Number(id[3]); var min = _id; var max = min; min += Math.min.apply( null, arr ); max += Math.max.apply( null, arr ); for(var k in update) { if(k >= min && k <= max) { var values = rgb_to_array(self.val()); var address = k - _id; if(address === Number(self.data('red'))) { values[0] = update[k]; } else if(address === Number(self.data('green'))) { values[1] = update[k]; } else if(address === Number(self.data('blue'))) { values[2] = update[k]; } self.val(array_to_rgb(values)); } } }); }); </script> </head> <body> <div class="navbar navbar-inverse"> <div class="navbar-inner"> <ul class="nav" id="myTab"> <li class="active"><a href="#home" data-toggle="tab">Home</a></li> <li><a href="#sliders" data-toggle="tab">Sliders</a></li> <li><a href="#anim" data-toggle="tab">Animations</a></li> <!--<li><a href="#scripts" data-toggle="tab">Scripts</a></li>--> </ul> </div> </div> <div class="container-fluid"> <div class="tab-content"> <div id="home" class="tab-pane active"> <div class="row-fluid" id="presets"> </div> </div> <div id="sliders" class="tab-pane"> </div> <div id="anim" class="tab-pane"> </div> <div id="scripts" class="tab-pane"> </div> </div> </div> </body> </html>