2019-12-08 16:16:33 +01:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<html lang=de">
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8" />
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
|
|
<title>LED Board</title>
|
|
|
|
<style>
|
|
|
|
body {background-color: #ccc; margin: 0; padding: 0; text-align: center;}
|
|
|
|
input {background-color: #ccc; border-radius: 2px;}
|
2019-12-08 20:59:43 +01:00
|
|
|
.menu { background-color: rgb(4, 0, 59); color: #ccc; padding: 1.2em; width: 100%; box-sizing: border-box; margin-bottom: 1em;}
|
|
|
|
.btn { background-color: #005; border-radius: 2px; color:#ccc; box-shadow: 5px, 5px, 5px, #000; padding: 5px;}
|
2019-12-08 16:16:33 +01:00
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div class="menu">
|
|
|
|
IP: <input type="text" id="ip" value="10.23.42.24">
|
|
|
|
<div style="width: 2em; display: inline-block;" ></div>
|
2019-12-08 20:59:43 +01:00
|
|
|
Port: <input type="text" id="port" value="81" style="width: 2.5em;">
|
2019-12-08 16:16:33 +01:00
|
|
|
<div style="width: 2em; display: inline-block;" ></div>
|
|
|
|
Panel width: <input type="text" id="width" value="32" style="width: 2.5em;" onchange="creatGUI()">
|
|
|
|
height: <input type="text" id="height" value="40" style="width: 2.5em;" onchange="creatGUI()">
|
|
|
|
<div style="width: 1em; display: inline-block;" ></div>
|
|
|
|
Connection state: <div id="connectionState" onclick="toggleConnection()" style="background-color: red; display: inline-block; width: 1em; height: 1em; border-radius: 0.5em;"></div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
2019-12-08 20:59:43 +01:00
|
|
|
<input class="btn" type="button" value="clear" onclick="clearCanvas()">
|
|
|
|
<input type="file" id="fileupload" value="upload file" style="display: none;" />
|
|
|
|
<label class="btn" for="fileupload">upload a file</label>
|
|
|
|
<br />
|
|
|
|
<canvas id="can" style="background-color:#000; margin: 1em;"></canvas> <br />
|
|
|
|
<textarea id="textInput"></textarea><br />
|
|
|
|
<input type="button" value="print" onclick="textInputChanged()" />
|
2019-12-08 16:16:33 +01:00
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
|
|
var socket;
|
|
|
|
document.onload = openWebSocket();
|
|
|
|
var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
|
|
|
|
|
|
|
|
var canvas, ctx = false,
|
|
|
|
prevX = 0,
|
|
|
|
currX = 0,
|
|
|
|
prevY = 0,
|
|
|
|
currY = 0,
|
|
|
|
dragMode = false;
|
|
|
|
|
|
|
|
var onColor = "#fd0";
|
|
|
|
var offColor = "#310";
|
|
|
|
|
|
|
|
var pixelBuffer = new Array(0);
|
|
|
|
var scaling;
|
|
|
|
var xMax, yMax;
|
|
|
|
var changeFlag = false;
|
|
|
|
var frameRate = 3; //frames per second
|
|
|
|
|
|
|
|
creatGUI();
|
|
|
|
setTimeout(frameRefresh, 1000 / frameRate);
|
|
|
|
|
|
|
|
|
|
|
|
function openWebSocket()
|
|
|
|
{
|
|
|
|
ip = document.getElementById('ip').value;
|
|
|
|
port = document.getElementById('port').value;
|
|
|
|
panelWidthElement = document.getElementById('width');
|
|
|
|
panelHeightElement = document.getElementById('height');
|
|
|
|
|
|
|
|
displayView = document.getElementById("can");
|
|
|
|
console.log("connect to " + ip + ":" + port);
|
|
|
|
|
|
|
|
socket = new WebSocket('ws://' + ip + ':'+port+'', ['arduino']);
|
|
|
|
socket.onopen = function ()
|
|
|
|
{
|
|
|
|
console.log('connected');
|
|
|
|
document.getElementById('connectionState').style.backgroundColor = "#3d3";
|
|
|
|
};
|
|
|
|
|
|
|
|
socket.onerror = function (error)
|
|
|
|
{
|
|
|
|
console.log('WebSocket Error ', error);
|
|
|
|
document.getElementById('connectionState').style.backgroundColor = "#dd3";
|
|
|
|
};
|
|
|
|
|
|
|
|
socket.onclose = function ()
|
|
|
|
{
|
|
|
|
console.log('WebSocket connection closed');
|
|
|
|
document.getElementById('connectionState').style.backgroundColor = "#d33";
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function frameRefresh()
|
|
|
|
{
|
|
|
|
if(changeFlag==true && socket.readyState === WebSocket.OPEN)
|
|
|
|
{
|
|
|
|
changeFlag = false;
|
|
|
|
sendPixelBuffer();
|
|
|
|
console.log("refreshed");
|
|
|
|
}
|
|
|
|
|
|
|
|
setTimeout(frameRefresh, 1000 / frameRate);
|
|
|
|
}
|
|
|
|
|
|
|
|
function toggleConnection()
|
|
|
|
{
|
|
|
|
if(socket.readyState === WebSocket.CLOSED)
|
|
|
|
{
|
|
|
|
openWebSocket();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
socket.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function sendPixelBuffer()
|
|
|
|
{
|
|
|
|
header = new Uint8Array(6);
|
|
|
|
header[0] = Math.floor(xMax / 255);
|
|
|
|
header[1] = xMax % 255;
|
|
|
|
header[2] = Math.floor(yMax / 255);
|
|
|
|
header[3] = yMax % 255;
|
|
|
|
header[4] = 0;
|
|
|
|
header[5] = 0;
|
|
|
|
|
|
|
|
socket.send(header);
|
|
|
|
socket.send(pixelBuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
function creatGUI()
|
|
|
|
{
|
|
|
|
scaling = 10;//(document.width / 2) / panelWidthElement.value;
|
|
|
|
|
|
|
|
xMax = panelWidthElement.value;
|
|
|
|
yMax = panelHeightElement.value;
|
|
|
|
displayView.width = panelWidthElement.value*scaling;// + "px";
|
|
|
|
displayView.height = panelHeightElement.value*scaling;// + "px";
|
|
|
|
|
|
|
|
pixelBuffer = new Uint8Array(xMax*yMax);
|
|
|
|
|
|
|
|
initCanvas();
|
|
|
|
}
|
|
|
|
|
|
|
|
function clearCanvas()
|
|
|
|
{
|
|
|
|
ctx = canvas.getContext("2d");
|
|
|
|
ctx.clearRect(0, 0, displayView.width, displayView.height);
|
|
|
|
|
|
|
|
for(x = 0; x < xMax; x++)
|
|
|
|
{
|
|
|
|
|
|
|
|
for(y = 0; y < yMax; y++)
|
|
|
|
{
|
|
|
|
pixelBuffer[x, xMax*y] = 0;
|
|
|
|
drawDot(x*scaling+1, y*scaling +1, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function initCanvas() {
|
|
|
|
canvas = document.getElementById('can');
|
|
|
|
ctx = canvas.getContext("2d");
|
|
|
|
w = canvas.width;
|
|
|
|
h = canvas.height;
|
|
|
|
|
|
|
|
canvas.addEventListener("mousemove", function (e) {
|
|
|
|
findxy('move', e)
|
|
|
|
}, false);
|
|
|
|
canvas.addEventListener("mousedown", function (e) {
|
|
|
|
findxy('down', e)
|
|
|
|
}, false);
|
|
|
|
canvas.addEventListener("mouseup", function (e) {
|
|
|
|
findxy('up', e)
|
|
|
|
}, false);
|
|
|
|
canvas.addEventListener("mouseout", function (e) {
|
|
|
|
findxy('out', e)
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
clearCanvas();
|
|
|
|
}
|
|
|
|
|
|
|
|
function findxy(res, e) {
|
|
|
|
if (res == 'down') {
|
|
|
|
prevX = currX;
|
|
|
|
prevY = currY;
|
|
|
|
currX = e.clientX - canvas.offsetLeft;
|
|
|
|
currY = e.clientY - canvas.offsetTop;
|
|
|
|
|
|
|
|
drawDot(currX, currY);
|
|
|
|
dragMode = true;
|
|
|
|
}
|
|
|
|
if (res == 'up' || res == "out") {
|
|
|
|
dragMode = false;
|
|
|
|
}
|
|
|
|
if (res == 'move') {
|
|
|
|
if (dragMode) {
|
|
|
|
prevX = currX;
|
|
|
|
prevY = currY;
|
|
|
|
currX = e.clientX - canvas.offsetLeft;
|
|
|
|
currY = e.clientY - canvas.offsetTop;
|
|
|
|
drawDot(currX, currY);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawDot(x, y, forceOff=false)
|
|
|
|
{
|
|
|
|
x = Math.floor(x / scaling);
|
|
|
|
y = Math.floor(y / scaling);
|
|
|
|
|
|
|
|
if((pixelBuffer[x+xMax*y] == 0 || dragMode==true) && forceOff==false)
|
|
|
|
{
|
|
|
|
ctx.fillStyle = onColor;
|
|
|
|
if(pixelBuffer[x+xMax*y] != 1)
|
|
|
|
{
|
|
|
|
changeFlag = true;
|
|
|
|
}
|
|
|
|
pixelBuffer[x+xMax*y] = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ctx.fillStyle = offColor;
|
|
|
|
|
|
|
|
if(pixelBuffer[x+xMax*y] != 0)
|
|
|
|
{
|
|
|
|
changeFlag = true;
|
|
|
|
}
|
|
|
|
pixelBuffer[x+xMax*y] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.arc(x * scaling + scaling/2, y * scaling + scaling/2, scaling/2, 0, 2 * Math.PI);
|
|
|
|
|
|
|
|
ctx.fill();
|
|
|
|
ctx.stroke();
|
|
|
|
}
|
|
|
|
|
2019-12-08 20:59:43 +01:00
|
|
|
function displayBufferContent()
|
|
|
|
{
|
|
|
|
dragMode = true;
|
|
|
|
for(x = 0; x < xMax; x++)
|
|
|
|
{
|
|
|
|
for(y = 0; y < yMax; y++)
|
|
|
|
{
|
|
|
|
if(pixelBuffer[x + xMax*y] != 0)
|
|
|
|
{
|
|
|
|
drawDot(x*scaling+1, y*scaling +1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
drawDot(x*scaling+1, y*scaling +1, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dragMode = false;
|
|
|
|
changeFlag = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//====================================================================
|
|
|
|
//========= image upload functione... ==========
|
|
|
|
//====================================================================
|
|
|
|
|
|
|
|
document.getElementById("fileupload").addEventListener('change', imageChanged, false);
|
|
|
|
hiddenCanvas = document.createElement("canvas");
|
|
|
|
hiddenCtx = hiddenCanvas.getContext('2d');
|
|
|
|
|
|
|
|
function imageChanged(evt)
|
|
|
|
{
|
|
|
|
|
|
|
|
var file = evt.target.files[0];
|
|
|
|
if (!file.type.match('image.*'))
|
|
|
|
{
|
|
|
|
alert("wrong file format");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var reader = new FileReader();
|
|
|
|
reader.onload = function (event)
|
|
|
|
{
|
|
|
|
var img = new Image();
|
|
|
|
img.src = event.target.result;
|
|
|
|
img.onload = function()
|
|
|
|
{
|
|
|
|
width = img.width;
|
|
|
|
height = img.height;
|
|
|
|
if (width > height)
|
|
|
|
{
|
|
|
|
if (width > xMax)
|
|
|
|
{
|
|
|
|
height *= xMax / width;
|
|
|
|
width = xMax;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (height > yMax)
|
|
|
|
{
|
|
|
|
width *= yMax / height;
|
|
|
|
height = yMax;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
hiddenCanvas.width = width;
|
|
|
|
hiddenCanvas.height = height;
|
|
|
|
hiddenCtx.drawImage(img, 0, 0, width, height);
|
|
|
|
|
|
|
|
showHiddenCanvas();
|
|
|
|
|
|
|
|
}
|
|
|
|
img.src = event.target.result;
|
|
|
|
};
|
|
|
|
reader.readAsDataURL(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
function showHiddenCanvas()
|
|
|
|
{
|
|
|
|
for(var y = 0; y < yMax; y++)
|
|
|
|
{
|
|
|
|
for(var x = 0; x < xMax; x++)
|
|
|
|
{
|
|
|
|
var p = hiddenCtx.getImageData(x, y, 1, 1).data;
|
|
|
|
if((p[0] < 128 || p[1] < 128 || p[2] < 128) && p[3] > 128)
|
|
|
|
{
|
|
|
|
pixelBuffer[x+xMax*y] = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pixelBuffer[x+xMax*y] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
displayBufferContent();
|
|
|
|
}
|
|
|
|
|
|
|
|
function printText(texttodraw)
|
|
|
|
{
|
|
|
|
hiddenCanvas.width = xMax;
|
|
|
|
hiddenCanvas.height = yMax;
|
|
|
|
|
|
|
|
var lines = texttodraw.split('\n');
|
|
|
|
|
|
|
|
hiddenCtx.clearRect(0, 0, hiddenCanvas.width, hiddenCanvas.height);
|
|
|
|
|
|
|
|
hiddenCtx.font = '10px Verdana';
|
|
|
|
hiddenCtx.textBaseline="top";
|
|
|
|
var lineheight = 10;
|
|
|
|
|
|
|
|
for (var j = 0; j<lines.length; j++)
|
|
|
|
{
|
|
|
|
hiddenCtx.fillText(lines[j], 0, 0 + (j*lineheight));
|
|
|
|
}
|
|
|
|
|
|
|
|
showHiddenCanvas();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function textInputChanged()
|
|
|
|
{
|
|
|
|
var text = document.getElementById("textInput").value;
|
|
|
|
printText(text);
|
|
|
|
}
|
|
|
|
|
2019-12-08 16:16:33 +01:00
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|