wolkd
Version:
Server and user interface to control WS2801 RGB LED strips via SPI
176 lines (153 loc) • 4.64 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>Wolk</title>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/skeleton.css">
<link rel="stylesheet" href="css/wolk.css">
<script src="js/reconnecting-websocket.min.js" charset="utf-8"></script>
<script src="js/draggabilly.pkgd.min.js"></script>
<script src="js/d3.min.js"></script>
<script src="js/wolk-client.js"></script>
<link rel="icon" type="image/png" href="img/icon.png">
</head>
<body>
<header>
<div class="container">
<div class="row">
<img src="img/wolk.svg" width="40%"/>
</div>
</div>
</header>
<div class="container">
<div class="row">
<h2>Patterns</h2>
<div id="patterns">
</div>
<h2>Modifiers</h2>
<div id="modifiers">
</div>
<h2>BPM</h2>
<div id="bpm" class="small-rectangle border">
</div>
<h2>Searchlight</h2>
<div id="searchlight-container" class="rectangle border">
<div id="searchlight" class="border">
</div>
</div>
</div>
<script>
function createSliders(url, container, wsEvent) {
function onDragMove(event, pointer, moveVector) {
var data = d3.select(this.element).datum();
var p = this.position.x / (this.element.parentElement.offsetWidth - this.element.offsetWidth);
p = Math.round(p * 100) / 100;
if (p <= 0.03) {
p = 0;
} else if (p >= 0.97) {
p = 1;
}
wolkSend(wsEvent, {
name: data.name,
value: p
});
}
function onDragEnd(event, pointer) {
// console.log(onDragEnd)
// console.log(this.element.id)
}
function onStaticClick(event, pointer) {
// TODO: turn on/off item on click?!
// console.log(onDragEnd)
// console.log(this.element.id)
}
var parentWidth = document.querySelector(container).offsetWidth;
// 140px;
d3.json(url, function(patterns) {
d3.select(container).selectAll('.drag')
.data(patterns)
.enter()
.append('div')
.attr('class', 'border drag')
.style('left', function(d) {
var left = d.value * (parentWidth - 140);
return left + 'px';
})
.html(function(d) {
return d.title;
})
.each(function(d) {
var draggie = new Draggabilly(this, {
axis: 'x',
containment: container
});
draggie.on('dragMove', onDragMove);
draggie.on('dragEnd', onDragEnd);
draggie.on('staticClick', onStaticClick);
});
});
}
createSliders('patterns', '#patterns', 'pattern');
createSliders('modifiers', '#modifiers', 'modifier');
</script>
<script>
var draggie = new Draggabilly('#searchlight', {
containment: '#searchlight-container'
});
draggie.on('dragMove', function() {
var px = this.position.x / (this.element.parentElement.offsetWidth - this.element.offsetWidth);
var py = this.position.y / (this.element.parentElement.offsetHeight - this.element.offsetHeight);
px = Math.abs(Math.round(px * 100) / 100);
py = Math.abs(Math.round(py * 100) / 100);
wolkSend('searchlight', {
x: px,
y: py
});
});
</script>
<script>
var inverted = false;
d3.select('#go').on('click', function() {
inverted = !inverted;
wolkSend('invert', inverted);
});
// BPM
var bpmTimeout;
var beats = [];
var firstMs;
var oldMs;
d3.select('#bpm').on('click', function() {
var ms = new Date().getTime();
if (bpmTimeout) {
clearTimeout(bpmTimeout);
}
bpmTimeout = setTimeout(function() {
beats = [];
firstMs = undefined;
oldMs = undefined;
}, 2000);
if (!firstMs) {
firstMs = ms;
}
if (oldMs) {
var duration = ms - oldMs;
beats.push(duration);
}
if (beats.length >= 4) {
var sum = beats.reduce(function(d1, d2) { return d1 + d2; });
var avgDuration = sum / beats.length;
wolkSend('bpm', {
startMs: firstMs,
bpm: Math.round(60 * 1000 / avgDuration)
});
}
oldMs = ms;
});
</script>
</body>
</html>