Skip to content

Instantly share code, notes, and snippets.

@gabonator
Created October 22, 2025 23:21
Show Gist options
  • Save gabonator/1043420fd624dfbb5f54bbb878198d4a to your computer and use it in GitHub Desktop.
Save gabonator/1043420fd624dfbb5f54bbb878198d4a to your computer and use it in GitHub Desktop.
laser projector cat&mouse anim
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>DMX Channel Configurator — Live Values</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body { font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; }
.channel-card { border-radius: 14px; background:white; padding:16px; box-shadow:0 6px 18px rgba(15,23,42,0.06); border:1px solid rgba(15,23,42,0.04); }
.range-bubble { font-size:0.75rem; padding:2px 8px; border-radius:999px; background:#f3f4f6; display:inline-block; margin-right:6px; }
input[type="range"]::-webkit-slider-runnable-track { height:10px; border-radius:8px; }
input[type="range"]::-moz-range-track { height:10px; border-radius:8px; }
input[type="range"] { height:28px; width:100%; }
</style>
</head>
<body class="bg-gray-100 min-h-screen p-6">
<h1 class="text-2xl font-bold mb-4">DMX Channel Configurator</h1>
<p class="text-sm text-gray-600 mb-6">Select a subrange with a radio button. If multiple values are allowed, adjust with the slider. The live text box below always reflects all 34 channel values.</p>
<div id="channels" class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3"></div>
<div class="mt-6 flex flex-col gap-2">
<label class="text-sm font-medium text-gray-700">All channel values (comma separated)</label>
<input id="liveValues" type="text" class="w-full p-2 border rounded-lg font-mono text-sm" readonly>
</div>
<div class="mt-4 flex gap-3">
<button id="exportBtn" class="px-4 py-2 rounded bg-blue-600 text-white hover:bg-blue-700">Export JSON</button>
<button id="resetBtn" class="px-4 py-2 rounded bg-gray-200 hover:bg-gray-300">Reset</button>
</div>
<pre id="output" class="mt-4 p-3 bg-black text-green-300 rounded overflow-auto max-h-60"></pre>
<script>
let ws;
/* ---------- Replace this array with your full 34-channel JSON ---------- */
const channels = [
{"channelItemList":[
{"name":"Black out A&B","value":0,"minValue":0,"maxValue":0},
{"name":"Auto","value":1,"minValue":1,"maxValue":99},
{"name":"Sound","value":100,"minValue":100,"maxValue":199},
{"name":"Reserved","value":200,"minValue":200,"maxValue":254},
{"name":"Black out A","value":255,"minValue":255,"maxValue":255}
], "channelName":"Black out","channelValue":0},
{"channelItemList":[
{"name":"Trans","value":0,"minValue":0,"maxValue":49},
{"name":"Turn back","value":50,"minValue":50,"maxValue":100},
{"name":"Away","value":100,"minValue":100,"maxValue":149},
{"name":"Reserved","value":150,"minValue":150,"maxValue":255}
],"channelName":"Outside & Size","channelValue":0},
{"channelItemList":[
{"name":"Gallery-1","value":0,"minValue":0,"maxValue":15},
{"name":"Gallery-2","value":16,"minValue":16,"maxValue":31},
{"name":"Gallery-3","value":32,"minValue":32,"maxValue":47},
{"name":"Gallery-4","value":48,"minValue":48,"maxValue":63},
{"name":"Gallery-5","value":64,"minValue":64,"maxValue":79},
{"name":"Gallery-6","value":80,"minValue":80,"maxValue":95},
{"name":"Gallery-7","value":96,"minValue":96,"maxValue":111},
{"name":"Gallery-8","value":112,"minValue":112,"maxValue":127},
{"name":"Gallery-9","value":128,"minValue":128,"maxValue":143},
{"name":"Gallery-10","value":144,"minValue":144,"maxValue":159},
{"name":"Gallery-11","value":160,"minValue":160,"maxValue":175},
{"name":"Gallery-12","value":176,"minValue":176,"maxValue":191},
{"name":"Gallery-13","value":192,"minValue":192,"maxValue":207},
{"name":"Gallery-14","value":208,"minValue":208,"maxValue":223},
{"name":"Gallery-15","value":224,"minValue":224,"maxValue":239},
{"name":"Gallery-0","value":240,"minValue":240,"maxValue":255}
],"channelName":"Gallery select","channelValue":0},
{"channelItemList":[
],"channelName":"Pattern","channelValue":0},
{"channelItemList":[
{"name":"Normal","value":0,"minValue":0,"maxValue":0},
{"name":"Zoom1","value":1,"minValue":1,"maxValue":31},
{"name":"Zoom2","value":32,"minValue":32,"maxValue":63},
{"name":"Zoom3","value":64,"minValue":64,"maxValue":95},
{"name":"Zoom4","value":96,"minValue":96,"maxValue":127},
{"name":"Zoom5","value":128,"minValue":128,"maxValue":159},
{"name":"Zoom6","value":160,"minValue":160,"maxValue":191},
{"name":"Zoom7","value":192,"minValue":192,"maxValue":223},
{"name":"Zoom8","value":224,"minValue":224,"maxValue":255}
],"channelName":"Zoom","channelValue":0},
{"channelItemList":[
{"name":"Angle","value":0,"minValue":0,"maxValue":63},
{"name":"Spin1","value":64,"minValue":64,"maxValue":95},
{"name":"Spin2","value":96,"minValue":96,"maxValue":127},
{"name":"Spin3","value":128,"minValue":128,"maxValue":159},
{"name":"Spin4","value":160,"minValue":160,"maxValue":191},
{"name":"Spin5","value":192,"minValue":192,"maxValue":223},
{"name":"Spin6","value":224,"minValue":224,"maxValue":255}
],"channelName":"Spin","channelValue":0},
{"channelItemList":[
{"name":"X-Position","value":0,"minValue":0,"maxValue":63},
{"name":"X-Move1","value":64,"minValue":64,"maxValue":95},
{"name":"X-Move2","value":96,"minValue":96,"maxValue":127},
{"name":"X-Move3","value":128,"minValue":128,"maxValue":159},
{"name":"X-Move4","value":160,"minValue":160,"maxValue":191},
{"name":"X-Move5","value":192,"minValue":192,"maxValue":223},
{"name":"X-Move6","value":224,"minValue":224,"maxValue":255}
],"channelName":"X-Move","channelValue":0},
{"channelItemList":[
{"name":"Y-Position","value":0,"minValue":0,"maxValue":63},
{"name":"Y-Move1","value":64,"minValue":64,"maxValue":95},
{"name":"Y-Move2","value":96,"minValue":96,"maxValue":127},
{"name":"Y-Move3","value":128,"minValue":128,"maxValue":159},
{"name":"Y-Move4","value":160,"minValue":160,"maxValue":191},
{"name":"Y-Move5","value":192,"minValue":192,"maxValue":223},
{"name":"Y-Move6","value":224,"minValue":224,"maxValue":255}
],"channelName":"Y-Move","channelValue":0},
{"channelItemList":[
{"name":"X-Size","value":0,"minValue":0,"maxValue":63},
{"name":"X-Zoom1","value":64,"minValue":64,"maxValue":95},
{"name":"X-Zoom2","value":96,"minValue":96,"maxValue":127},
{"name":"X-Zoom3","value":128,"minValue":128,"maxValue":159},
{"name":"X-Zoom4","value":160,"minValue":160,"maxValue":191},
{"name":"X-Zoom5","value":192,"minValue":192,"maxValue":223},
{"name":"X-Zoom6","value":224,"minValue":224,"maxValue":255}
],"channelName":"X-Zoom","channelValue":0},
{"channelItemList":[
{"name":"Y-Size","value":0,"minValue":0,"maxValue":63},
{"name":"Y-Zoom1","value":64,"minValue":64,"maxValue":95},
{"name":"Y-Zoom2","value":96,"minValue":96,"maxValue":127},
{"name":"Y-Zoom3","value":128,"minValue":128,"maxValue":159},
{"name":"Y-Zoom4","value":160,"minValue":160,"maxValue":191},
{"name":"Y-Zoom5","value":192,"minValue":192,"maxValue":223},
{"name":"Y-Zoom6","value":224,"minValue":224,"maxValue":255}
],"channelName":"Y-Zoom","channelValue":0},
{"channelItemList":[
{"name":"Normal","value":0,"minValue":0,"maxValue":0},
{"name":"Color Len","value":1,"minValue":1,"maxValue":255}
],"channelName":"Segment Color","channelValue":0},
{"channelItemList":[
{"name":"Normal","value":0,"minValue":0,"maxValue":7},
{"name":"Red","value":8,"minValue":8,"maxValue":15},
{"name":"Yellow","value":16,"minValue":16,"maxValue":23},
{"name":"Green","value":24,"minValue":24,"maxValue":31},
{"name":"Indigo","value":32,"minValue":32,"maxValue":39},
{"name":"Blue","value":40,"minValue":40,"maxValue":47},
{"name":"Purple","value":48,"minValue":48,"maxValue":55},
{"name":"White","value":56,"minValue":56,"maxValue":63},
{"name":"RGB-Change","value":64,"minValue":64,"maxValue":95},
{"name":"YIP-Change","value":96,"minValue":96,"maxValue":127},
{"name":"RYGIBPW-Change","value":128,"minValue":128,"maxValue":159},
{"name":"Color-Change","value":160,"minValue":160,"maxValue":191},
{"name":"Roll Color1","value":192,"minValue":192,"maxValue":223},
{"name":"Roll Color2","value":224,"minValue":224,"maxValue":255}
],"channelName":"Change color","channelValue":0},
{"channelItemList":[
{"name":"Normal","value":0,"minValue":0,"maxValue":63},
{"name":"Display black Line","value":64,"minValue":64,"maxValue":127},
{"name":"Display All Line","value":128,"minValue":128,"maxValue":159},
{"name":"Reserved","value":160,"minValue":160,"maxValue":255}
],"channelName":"Gloss","channelValue":0},
{"channelItemList":[
{"name":"Extend value","value":0,"minValue":0,"maxValue":255}
],"channelName":"Extend value","channelValue":0},
{"channelItemList":[
{"name":"Positive","value":0,"minValue":0,"maxValue":31},
{"name":"Negative","value":32,"minValue":32,"maxValue":63},
{"name":"Extend1","value":64,"minValue":64,"maxValue":95},
{"name":"Extend2","value":96,"minValue":96,"maxValue":127},
{"name":"Extend3","value":128,"minValue":128,"maxValue":159},
{"name":"Extend4","value":160,"minValue":160,"maxValue":191},
{"name":"Extend5","value":192,"minValue":192,"maxValue":223},
{"name":"Extend6","value":224,"minValue":224,"maxValue":255}
],"channelName":"Extend effect","channelValue":0},
{"channelItemList":[
{"name":"Curve value","value":0,"minValue":0,"maxValue":255}
],"channelName":"Curve value","channelValue":0},
{"channelItemList":[
{"name":"Filter1","value":0,"minValue":0,"maxValue":19},
{"name":"Filter2","value":20,"minValue":20,"maxValue":39},
{"name":"Filter3","value":40,"minValue":40,"maxValue":59},
{"name":"Filter4","value":60,"minValue":60,"maxValue":79},
{"name":"Filter5","value":80,"minValue":80,"maxValue":99},
{"name":"Filter6","value":100,"minValue":100,"maxValue":119},
{"name":"Filter7","value":120,"minValue":120,"maxValue":139},
{"name":"Filter8","value":140,"minValue":140,"maxValue":159},
{"name":"Filter9","value":160,"minValue":160,"maxValue":179},
{"name":"Filter10","value":180,"minValue":180,"maxValue":199},
{"name":"Filter11","value":200,"minValue":200,"maxValue":219},
{"name":"Filter12","value":220,"minValue":220,"maxValue":239},
{"name":"Filter13","value":240,"minValue":240,"maxValue":255}
],"channelName":"Filter & Screen size","channelValue":0},
{"channelItemList":[
{"name":"Black out B","value":0,"minValue":0,"maxValue":0},
{"name":"Auto","value":1,"minValue":1,"maxValue":99},
{"name":"Sound","value":100,"minValue":100,"maxValue":199},
{"name":"Reserved","value":200,"minValue":200,"maxValue":254},
{"name":"Reserved","value":255,"minValue":255,"maxValue":255}
],"channelName":"Black out","channelValue":0},
{"channelItemList":[
{"name":"Trans","value":0,"minValue":0,"maxValue":49},
{"name":"Turn back","value":50,"minValue":50,"maxValue":100},
{"name":"Away","value":100,"minValue":100,"maxValue":149},
{"name":"Reserved","value":150,"minValue":150,"maxValue":255}
],"channelName":"Outside & Size","channelValue":0},
{"channelItemList":[
{"name":"positive","value":0,"minValue":0,"maxValue":99},
{"name":"negative","value":100,"minValue":100,"maxValue":199},
{"name":"Reserved","value":200,"minValue":200,"maxValue":255}
],"channelName":"Array angle","channelValue":0},
{"channelItemList":[
],"channelName":"Pattern","channelValue":0},
{"channelItemList":[
{"name":"Normal","value":0,"minValue":0,"maxValue":0},
{"name":"Zoom1","value":1,"minValue":1,"maxValue":31},
{"name":"Zoom2","value":32,"minValue":32,"maxValue":63},
{"name":"Zoom3","value":64,"minValue":64,"maxValue":95},
{"name":"Zoom4","value":96,"minValue":96,"maxValue":127},
{"name":"Zoom5","value":128,"minValue":128,"maxValue":159},
{"name":"Zoom6","value":160,"minValue":160,"maxValue":191},
{"name":"Zoom7","value":192,"minValue":192,"maxValue":223},
{"name":"Zoom8","value":224,"minValue":224,"maxValue":255}
],"channelName":"Zoom","channelValue":0},
{"channelItemList":[
{"name":"Angle","value":0,"minValue":0,"maxValue":63},
{"name":"Spin1","value":64,"minValue":64,"maxValue":95},
{"name":"Spin2","value":96,"minValue":96,"maxValue":127},
{"name":"Spin3","value":128,"minValue":128,"maxValue":159},
{"name":"Spin4","value":160,"minValue":160,"maxValue":191},
{"name":"Spin5","value":192,"minValue":192,"maxValue":223},
{"name":"Spin6","value":224,"minValue":224,"maxValue":255}
],"channelName":"Spin","channelValue":0},
{"channelItemList":[
{"name":"X-Position","value":0,"minValue":0,"maxValue":63},
{"name":"X-Move1","value":64,"minValue":64,"maxValue":95},
{"name":"X-Move2","value":96,"minValue":96,"maxValue":127},
{"name":"X-Move3","value":128,"minValue":128,"maxValue":159},
{"name":"X-Move4","value":160,"minValue":160,"maxValue":191},
{"name":"X-Move5","value":192,"minValue":192,"maxValue":223},
{"name":"X-Move6","value":224,"minValue":224,"maxValue":255}
],"channelName":"X-Move","channelValue":0},
{"channelItemList":[
{"name":"Y-Position","value":0,"minValue":0,"maxValue":63},
{"name":"Y-Move1","value":64,"minValue":64,"maxValue":95},
{"name":"Y-Move2","value":96,"minValue":96,"maxValue":127},
{"name":"Y-Move3","value":128,"minValue":128,"maxValue":159},
{"name":"Y-Move4","value":160,"minValue":160,"maxValue":191},
{"name":"Y-Move5","value":192,"minValue":192,"maxValue":223},
{"name":"Y-Move6","value":224,"minValue":224,"maxValue":255}
],"channelName":"Y-Move","channelValue":0},
{"channelItemList":[
{"name":"X-Size","value":0,"minValue":0,"maxValue":63},
{"name":"X-Zoom1","value":64,"minValue":64,"maxValue":95},
{"name":"X-Zoom2","value":96,"minValue":96,"maxValue":127},
{"name":"X-Zoom3","value":128,"minValue":128,"maxValue":159},
{"name":"X-Zoom4","value":160,"minValue":160,"maxValue":191},
{"name":"X-Zoom5","value":192,"minValue":192,"maxValue":223},
{"name":"X-Zoom6","value":224,"minValue":224,"maxValue":255}
],"channelName":"X-Zoom","channelValue":0},
{"channelItemList":[
{"name":"Y-Size","value":0,"minValue":0,"maxValue":63},
{"name":"Y-Zoom1","value":64,"minValue":64,"maxValue":95},
{"name":"Y-Zoom2","value":96,"minValue":96,"maxValue":127},
{"name":"Y-Zoom3","value":128,"minValue":128,"maxValue":159},
{"name":"Y-Zoom4","value":160,"minValue":160,"maxValue":191},
{"name":"Y-Zoom5","value":192,"minValue":192,"maxValue":223},
{"name":"Y-Zoom6","value":224,"minValue":224,"maxValue":255}
],"channelName":"Y-Zoom","channelValue":0},
{"channelItemList":[
{"name":"Normal","value":0,"minValue":0,"maxValue":0},
{"name":"Color Len","value":1,"minValue":1,"maxValue":255}
],"channelName":"Segment Color","channelValue":0},
{"channelItemList":[
{"name":"Normal","value":0,"minValue":0,"maxValue":7},
{"name":"Red","value":8,"minValue":8,"maxValue":15},
{"name":"Yellow","value":16,"minValue":16,"maxValue":23},
{"name":"Green","value":24,"minValue":24,"maxValue":31},
{"name":"Indigo","value":32,"minValue":32,"maxValue":39},
{"name":"Blue","value":40,"minValue":40,"maxValue":47},
{"name":"Purple","value":48,"minValue":48,"maxValue":55},
{"name":"White","value":56,"minValue":56,"maxValue":63},
{"name":"RGB-Change","value":64,"minValue":64,"maxValue":95},
{"name":"YIP-Change","value":96,"minValue":96,"maxValue":127},
{"name":"RYGIBPW-Change","value":128,"minValue":128,"maxValue":159},
{"name":"Color-Change","value":160,"minValue":160,"maxValue":191},
{"name":"Roll Color1","value":192,"minValue":192,"maxValue":223},
{"name":"Roll Color2","value":224,"minValue":224,"maxValue":255}
],"channelName":"Change color","channelValue":0},
{"channelItemList":[
{"name":"Normal","value":0,"minValue":0,"maxValue":63},
{"name":"Display black Line","value":64,"minValue":64,"maxValue":127},
{"name":"Display black All","value":128,"minValue":128,"maxValue":159},
{"name":"Array1","value":160,"minValue":160,"maxValue":191},
{"name":"Array2","value":192,"minValue":192,"maxValue":255}
],"channelName":"Gloss & Array","channelValue":0},
{"channelItemList":[
{"name":"Extend value","value":0,"minValue":0,"maxValue":255}
],"channelName":"Extend value","channelValue":0},
{"channelItemList":[
{"name":"Positive","value":0,"minValue":0,"maxValue":31},
{"name":"Negative","value":32,"minValue":32,"maxValue":63},
{"name":"Extend1","value":64,"minValue":64,"maxValue":95},
{"name":"Extend2","value":96,"minValue":96,"maxValue":127},
{"name":"Extend3","value":128,"minValue":128,"maxValue":159},
{"name":"Extend","value":160,"minValue":160,"maxValue":191},
{"name":"Roll Color1","value":192,"minValue":192,"maxValue":223},
{"name":"Roll Color2","value":224,"minValue":224,"maxValue":255}
],"channelName":"Extend effect","channelValue":0},
{"channelItemList":[
{"name":"Curve value","value":0,"minValue":0,"maxValue":255}
],"channelName":"Curve value","channelValue":0},
{"channelItemList":[
{"name":"Reserved","value":0,"minValue":0,"maxValue":19},
{"name":"Reserved","value":20,"minValue":20,"maxValue":39},
{"name":"Reserved","value":40,"minValue":40,"maxValue":59},
{"name":"Reserved","value":60,"minValue":60,"maxValue":79},
{"name":"Reserved","value":80,"minValue":80,"maxValue":99},
{"name":"Reserved","value":100,"minValue":100,"maxValue":119},
{"name":"Reserved","value":120,"minValue":120,"maxValue":139},
{"name":"Reserved","value":140,"minValue":140,"maxValue":159},
{"name":"Reserved","value":160,"minValue":160,"maxValue":179},
{"name":"Reserved","value":180,"minValue":180,"maxValue":199},
{"name":"Reserved","value":200,"minValue":200,"maxValue":219},
{"name":"Reserved","value":220,"minValue":220,"maxValue":239},
{"name":"Screen size","value":240,"minValue":240,"maxValue":255}
],"channelName":"Screen size","channelValue":0}
];
/* ---------------------------------------------------------------------- */
const container = document.getElementById('channels');
const output = document.getElementById('output');
const liveInput = document.getElementById('liveValues');
const values = new Array(channels.length).fill(0);
function updateLiveValues() {
liveInput.value = values.join(',');
dmx(values)
}
channels.forEach((ch, idx) => {
const id = `ch${idx}`;
const card = document.createElement('div');
card.className = 'channel-card';
card.innerHTML = `
<div class="flex justify-between items-baseline mb-2">
<div>
<div class="font-medium">${ch.channelName || 'Channel ' + (idx+1)}</div>
<div class="text-xs text-gray-500">#${idx+1}</div>
</div>
<div class="text-sm text-gray-600">Value: <span id="${id}-val">${ch.channelValue||0}</span></div>
</div>
<div id="${id}-radios" class="flex flex-col gap-1 mb-3"></div>
<div id="${id}-sliderWrap" class="hidden">
<input type="range" id="${id}-slider" min="0" max="255" value="${ch.channelValue||0}">
<div class="flex justify-between text-xs text-gray-500"><span>Min</span><span>Max</span></div>
</div>
`;
container.appendChild(card);
const radiosDiv = document.getElementById(`${id}-radios`);
const sliderWrap = document.getElementById(`${id}-sliderWrap`);
const slider = document.getElementById(`${id}-slider`);
const valLabel = document.getElementById(`${id}-val`);
// --- build radios ---
if (ch.channelItemList && ch.channelItemList.length) {
ch.channelItemList.forEach((it, j) => {
const rid = `${id}-r-${j}`;
const label = document.createElement('label');
label.className = 'flex items-center gap-2 cursor-pointer text-sm';
label.innerHTML = `<input type="radio" name="${id}-r" id="${rid}" data-min="${it.minValue}" data-max="${it.maxValue}" value="${it.value}">
<span>${it.name} (${it.minValue}-${it.maxValue})</span>`;
radiosDiv.appendChild(label);
});
} else {
radiosDiv.innerHTML = `<div class="text-sm text-gray-500">No subranges (0–255)</div>`;
sliderWrap.classList.remove('hidden');
}
// --- when a radio is picked ---
radiosDiv.addEventListener('change', e => {
if (!e.target.matches('input[type=radio]')) return;
const min = Number(e.target.dataset.min);
const max = Number(e.target.dataset.max);
slider.min = min;
slider.max = max;
if (min === max) {
sliderWrap.classList.add('hidden');
valLabel.textContent = min;
values[idx] = min;
} else {
sliderWrap.classList.remove('hidden');
slider.value = min;
valLabel.textContent = slider.value;
values[idx] = Number(slider.value);
}
updateLiveValues();
});
// --- when slider moves ---
slider.addEventListener('input', e => {
const val = Number(e.target.value);
valLabel.textContent = val;
values[idx] = val;
updateLiveValues();
});
});
// --- Export JSON array ---
document.getElementById('exportBtn').addEventListener('click', () => {
output.textContent = JSON.stringify(values, null, 2);
});
// --- Reset everything ---
document.getElementById('resetBtn').addEventListener('click', () => {
document.querySelectorAll('input[type=radio]').forEach(r => r.checked = false);
document.querySelectorAll('input[type=range]').forEach(sl => { sl.value = 0; sl.parentElement.classList.add('hidden'); });
document.querySelectorAll('[id$="-val"]').forEach(v => v.textContent = '0');
values.fill(0);
updateLiveValues();
output.textContent = '';
});
// initial
updateLiveValues();
//const WebSocket = require('ws');
const WS_URL = 'ws://192.168.1.105:8080';
ws = new WebSocket(WS_URL);
// Connection opened
ws.addEventListener("open", (event) => {
console.log("opened")
// socket.send("Hello Server!");
});
ws.addEventListener("close", (event) => {
console.log("closed")
// socket.send("Hello Server!");
});
// Listen for messages
ws.addEventListener("message", (event) => {
console.log("Message from server ", event.data);
});
function dmx(buffer)
{
if (!ws) return
var dmxBuffer = [170, 4, 0, 90].concat(shortArrayToBytes([6+buffer.length])).concat(buffer);
console.log(dmxBuffer)
return ws.send(new Uint8Array(dmxBuffer));
}
function shortArrayToBytes(arr)
{
var out = [];
for (var i in arr)
{
var x = arr[i];
out.push(x & 0xff);
out.push(x >> 8);
}
return out;
}
</script>
</body>
</html>
let dmxEffect = ['Black out', 'Outside & Size', 'Gallery select',
'Pattern', 'Zoom', 'Spin', 'X-Move', 'Y-Move', 'X-Zoom', 'Y-Zoom',
'Segment Color', 'Change color', 'Gloss', 'Extend value', 'Extend effect', 'Curve value', 'Filter & Screen size']
var writer = require("../tools/tf1writer");
var Preview = require("../tools/preview").Preview;
var preview = new Preview;
function calcPattern(pat)
{
var ofsx = -400;
var ofsy = -500;
var scalex = 4;
var scaley = -2;
var p, colors;
switch (pat)
{
case 0:
p = [[{"x":146.74,"y":206.34},{"x":169,"y":313.53},{"x":250.12,"y":409.97},{"x":358.36,"y":436.85},{"x":455.76,"y":404.38},{"x":505.16,"y":339.84},{"x":526.8,"y":235.66},{"x":503.12,"y":70.33},{"x":432.7,"y":176.6},{"x":355.97,"y":151.72},{"x":248.03,"y":168.93},{"x":190.43,"y":67.2},{"x":146.78,"y":206.25}],[{"x":221.2,"y":212.8},{"x":285.06,"y":214.61},{"x":319.19,"y":254.49},{"x":301.11,"y":276.7},{"x":249.46,"y":267.99},{"x":221.07,"y":220.15}],[{"x":463.05,"y":212.65},{"x":395.52,"y":217.46},{"x":375.44,"y":250.5},{"x":385.45,"y":270.58},{"x":438.79,"y":272.64},{"x":464.34,"y":226.75}],[{"x":346.33,"y":327.3},{"x":330.11,"y":300.53},{"x":371.2,"y":300.77},{"x":350.63,"y":341.62},{"x":353.98,"y":383.68},{"x":382.66,"y":402.63},{"x":428.82,"y":389.3},{"x":438.55,"y":365.88}],[{"x":352.98,"y":384.39},{"x":335.36,"y":406.96},{"x":300.16,"y":394.4},{"x":283.6,"y":368.92}],[{"x":210.87,"y":310.09},{"x":85.71,"y":352.13}],[{"x":225.57,"y":336.97},{"x":145.48,"y":377.12}],[{"x":481.96,"y":301.25},{"x":588.88,"y":356.54}],[{"x":472.33,"y":326.93},{"x":532.52,"y":383.52}],[{"x":272.43,"y":232.57},{"x":272.31,"y":257.87}],[{"x":418.71,"y":228.91},{"x":418.71,"y":257.65}]];
colors = [1, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1]
break;
case 1:
p = [[{"x":352.18,"y":187.13},{"x":374.48,"y":214.18},{"x":444.32,"y":217.84},{"x":493.08,"y":244.95},{"x":520.09,"y":288.39},{"x":518.22,"y":355.41},{"x":481.82,"y":373.95},{"x":427.97,"y":367.46},{"x":397.12,"y":327.32},{"x":373.62,"y":293.16},{"x":421.46,"y":366.85},{"x":450.42,"y":419.42},{"x":499.32,"y":526.54},{"x":480.34,"y":592.69},{"x":419.21,"y":610.35},{"x":360.87,"y":597.52},{"x":283.07,"y":590.11},{"x":241.16,"y":537.11},{"x":231.14,"y":444.82},{"x":244.61,"y":400.2},{"x":266.82,"y":336.29},{"x":290.32,"y":300.47},{"x":255.3,"y":351.75},{"x":211.47,"y":378.73},{"x":171.2,"y":348.94},{"x":160.55,"y":292.23},{"x":179.79,"y":244.46},{"x":232.16,"y":225.12},{"x":280.5,"y":217.2},{"x":314.15,"y":180.47},{"x":325.88,"y":147.15},{"x":352.12,"y":185.45}],[{"x":360.78,"y":601.22},{"x":390.73,"y":653.35},{"x":394.41,"y":690.47},{"x":352.23,"y":708.36}],[{"x":295.93,"y":251.32},{"x":302.76,"y":253.64}],[{"x":355.59,"y":250.79},{"x":362.42,"y":248.28}]]
colors = [1, 1, 4, 4, 1, 1, 1, 1, 1, 1, 1]
ofsx += 50;
break
case 2:
ofsx = 0; ofsy = 500;
scalex = 2; scaley = 0.7;
p = [[{x:-500, y:-500}, {x:+500, y:-500}, {x:+500, y:+500}, {x:-500, y:+500}, {x:-500, y:-500}]]
colors = [4]
break;
case 3:
ofsx = 0; ofsy = 500;
scalex = 2; scaley = 0.7;
p = [[{x:0, y:-500}, {x:+500, y:0}, {x:0, y:+500}, {x:-500, y:0}, {x:0, y:-500}]]
colors = [1]
break;
case 4:
ofsx = 0; ofsy = 500;
scalex = 2; scaley = 0.7;
p = [[{x:0, y:-500}, {x:+500, y:0}, {x:0, y:+500}, {x:-500, y:0}, {x:0, y:-500},
{x:0, y:500}, {x:0, y:0}, {x:-500, y:0}, {x:500, y:0}]]
colors = [1]
break;
}
var parts = [];
var all = [];
for (var part of p)
{
parts.push(part.map(p=>writer.Cartesian(1, (p.x+ofsx)*scalex, (p.y+ofsy)*scaley)));
}
for (var part of parts)
{
let c = colors.shift()
if (all.length)
all.push({...part[0], c:0})
all = [...all, ...part.map(pt=>({...pt, c:c}))]
all.push({...part[part.length-1], c:0})
}
return all;
}
function fmin()
{
const showA = true
const showB = true
var _dmx = new Array(34).fill(0);
// cat
_dmx[dmxEffect.indexOf("Black out")] = showA ? 1 : 255;
_dmx[dmxEffect.indexOf("Black out")+17] = showB ? 1 : 0;
// _dmx[dmxEffect.indexOf("Outside & Size")] = 127;
_dmx[dmxEffect.indexOf("X-Move")] = 104;
_dmx[dmxEffect.indexOf("Y-Move")] = 33;
// mouse
_dmx[dmxEffect.indexOf("Y-Move")+17] = 193;
_dmx[dmxEffect.indexOf("X-Zoom")+17] = 14;
_dmx[dmxEffect.indexOf("Y-Zoom")+17] = 14;
_dmx[dmxEffect.indexOf("Spin")+17] = 130;
return _dmx;
}
function send()
{
var geometry0 = new writer.TF1Writer().buildGeometry(calcPattern(0));
var geometry1 = new writer.TF1Writer().buildGeometry(calcPattern(1));
var dmx = fmin();
var enc16 = x => [x & 255, x >> 8];
var dmxbuffer = [170, 4, 0, 90, ...enc16(6+dmx.length), ...dmx]
var preamble = [0xaa, 5, 0, 90, ...enc16(8), ...enc16(geometry0.length+geometry1.length+10)];
var geometry = [
0xaa, 6, 0, 90,
...enc16(10+geometry0.length+geometry1.length),
...enc16(geometry0.length-1),
...enc16(geometry0.length+geometry1.length-1),
...geometry0,
...geometry1,
];
return Promise.resolve()
.then( () => preview.ws.send(preamble) )
.then(()=> new Promise(resolve => setTimeout(resolve, 300)))
.then( () => preview.ws.send(geometry) )
.then(()=> new Promise(resolve => setTimeout(resolve, 300)))
.then( () => preview.ws.send(dmxbuffer) )
.then(()=> new Promise(resolve => setTimeout(resolve, 300)))
}
preview.connect("00:18:E4:35:5F:2A", 1)
.then( () => send() )
.then( () => preview.disconnect() )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment