197 lines
5.4 KiB
HTML
197 lines
5.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, user-scalable=no">
|
|
<title>Sporttafel</title>
|
|
<link rel="icon" href="icon.svg">
|
|
<style>
|
|
body {
|
|
font-family: sans-serif;
|
|
font-size: 8vw;
|
|
margin: 0;
|
|
}
|
|
|
|
button {
|
|
width: 33vmin;
|
|
font-size: 9vw;
|
|
}
|
|
|
|
button.cancel {
|
|
width: 15vmin;
|
|
height: 15vmin;
|
|
}
|
|
|
|
table {
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
td {
|
|
text-align: center;
|
|
}
|
|
|
|
svg {
|
|
border: 1px solid black;
|
|
width: 100%;
|
|
height: calc(11 / 27 * 100%);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<svg width="800" height="325" id="display" style="background-color: black">
|
|
</svg>
|
|
<table>
|
|
<tr>
|
|
<td>
|
|
<button onclick="get('/action/cancel')" class="cancel">✗</button>
|
|
</td>
|
|
<td>
|
|
<button onclick="get('/action/up')">↑</button>
|
|
</td>
|
|
<td> </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<button onclick="get('/action/left')">←</button>
|
|
</td>
|
|
<td>
|
|
<button onclick="get('/action/confirm')">✓</button>
|
|
</td>
|
|
<td>
|
|
<button onclick="get('/action/right')">→</button>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> </td>
|
|
<td>
|
|
<button onclick="get('/action/down')">↓</button>
|
|
</td>
|
|
<td> </td>
|
|
</tr>
|
|
|
|
<script>
|
|
|
|
const DEV_HOST = "10.0.0.119";
|
|
|
|
const S = 100 / 27;
|
|
|
|
const display = document.getElementById("display");
|
|
|
|
const segments = [];
|
|
|
|
function url(protocol, path) {
|
|
const hostPart = location.host.substring(0, location.host.indexOf(":"))
|
|
const isLocal = hostPart === "" || hostPart === "localhost" || hostPart === "0";
|
|
const host = isLocal ? DEV_HOST : hostPart;
|
|
const port = isLocal ? "80" : location.port;
|
|
return `${protocol}://${host}:${port}${path}`;
|
|
}
|
|
|
|
function get(path) {
|
|
const request = new XMLHttpRequest();
|
|
request.open("GET", url("http", path), true);
|
|
request.send();
|
|
}
|
|
|
|
function drawDigit(x, y) {
|
|
drawPixel(x, y, 0, 3);
|
|
drawPixel(x, y, 0, 2);
|
|
drawPixel(x, y, 0, 1);
|
|
|
|
drawPixel(x, y, 1, 0);
|
|
drawPixel(x, y, 2, 0);
|
|
drawPixel(x, y, 3, 0);
|
|
|
|
drawPixel(x, y, 4, 1);
|
|
drawPixel(x, y, 4, 2);
|
|
drawPixel(x, y, 4, 3);
|
|
|
|
drawPixel(x, y, 4, 5);
|
|
drawPixel(x, y, 4, 6);
|
|
drawPixel(x, y, 4, 7);
|
|
|
|
drawPixel(x, y, 3, 8);
|
|
drawPixel(x, y, 2, 8);
|
|
drawPixel(x, y, 1, 8);
|
|
|
|
drawPixel(x, y, 0, 7);
|
|
drawPixel(x, y, 0, 6);
|
|
drawPixel(x, y, 0, 5);
|
|
|
|
drawPixel(x, y, 1, 4);
|
|
drawPixel(x, y, 2, 4);
|
|
drawPixel(x, y, 3, 4);
|
|
}
|
|
|
|
function drawPixel(offsetRasterX, offsetRasterY, innerRasterX, innerRasterY) {
|
|
const segment = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
const x = (offsetRasterX + innerRasterX) * S;
|
|
const y = (offsetRasterY + innerRasterY) * S;
|
|
segment.setAttribute("x", x + "vw");
|
|
segment.setAttribute("y", y + "vw");
|
|
segment.setAttribute("width", S + "vw");
|
|
segment.setAttribute("height", S + "vw");
|
|
segment.setAttribute("stroke", "white");
|
|
segment.setAttribute("fill", "none");
|
|
segment.setAttribute("id", "segment" + segments.length);
|
|
display.appendChild(segment);
|
|
segments.push(segment);
|
|
}
|
|
|
|
function drawDisplay(rasterX, rasterY) {
|
|
drawDigit(rasterX, rasterY);
|
|
rasterX += 6;
|
|
drawDigit(rasterX, rasterY);
|
|
rasterX += 6;
|
|
drawPixel(rasterX, rasterY, 0, 0);
|
|
drawPixel(rasterX, rasterY + 2, 0, 0);
|
|
drawPixel(rasterX, rasterY + 6, 0, 0);
|
|
drawPixel(rasterX, rasterY + 8, 0, 0);
|
|
rasterX += 2;
|
|
drawDigit(rasterX, rasterY);
|
|
rasterX += 6;
|
|
drawDigit(rasterX, rasterY);
|
|
}
|
|
|
|
function connect() {
|
|
console.log("connecting websocket...");
|
|
const socket = new WebSocket(url("ws", "/ws"));
|
|
socket.timeout = 1;
|
|
socket.addEventListener('open', _ => {
|
|
console.log('websocket connected');
|
|
segments.forEach(segment => {
|
|
segment.setAttribute("fill", "none");
|
|
segment.setAttribute("stroke", "none");
|
|
});
|
|
});
|
|
socket.addEventListener('message', event => {
|
|
const len = event.data.length;
|
|
let index = 0;
|
|
let start = 0;
|
|
while (start < len) {
|
|
const end = start + 3;
|
|
const color = event.data.substring(start, end);
|
|
const segment = segments[index];
|
|
segment.setAttribute("fill", "#" + color)
|
|
index++;
|
|
start = end;
|
|
}
|
|
});
|
|
socket.addEventListener('close', _ => {
|
|
console.log('websocket disconnected');
|
|
segments.forEach(segment => {
|
|
segment.setAttribute("fill", "none");
|
|
segment.setAttribute("stroke", "white");
|
|
});
|
|
setTimeout(connect, 1000);
|
|
});
|
|
}
|
|
|
|
drawDisplay(1, 1);
|
|
setTimeout(connect, 1000);
|
|
|
|
</script>
|
|
|
|
</table>
|
|
</body>
|
|
</html> |