<!DOCTYPE html> <title>Explore the Torus</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> body { color: white; background-color: black; text-align: center; } a { color: white; } img { max-width: 100%; image-rendering: pixelated; } table { margin: auto; } button.arr { font-size: 150%; } </style> <p> <a href="ssh://torus@ascii.town"><code>ssh torus@ascii.town</code></a> <p> <img id="tile" src="tile.png"> <table> <tr> <td rowspan="2"> <button id="larr" class="arr" type="button">←</button> </td> <td><button id="uarr" class="arr" type="button">↑</button></td> <td rowspan="2"> <button id="rarr" class="arr" type="button">→</button> </td> </tr> <tr> <td><button id="darr" class="arr" type="button">↓</button></td> </tr> <tr> <td colspan="3"><button id="home" type="button">HOME</button></td> </tr> </table> <p> This is AGPLv3 Free Software! Code is available from <a href="https://code.causal.agency/june/torus">Code Toilet</a>. <script> let tile = document.getElementById("tile"); let larr = document.getElementById("larr"); let darr = document.getElementById("darr"); let uarr = document.getElementById("uarr"); let rarr = document.getElementById("rarr"); let state = new URLSearchParams(document.location.hash.slice(1)); function setImage() { let url = new URL(tile.src); url.search = "?" + state.toString(); tile.src = url.toString(); } setImage(); function setState(x, y) { state.set("x", x); state.set("y", y); history.pushState(state.toString(), "", "#" + state.toString()); setImage(); } function move(dx, dy) { setState(+state.get("x") + dx, +state.get("y") + dy); } window.onpopstate = function(event) { state = new URLSearchParams(event.state); setImage(); } home.onclick = () => setState(0, 0); larr.onclick = () => move(-1, 0); darr.onclick = () => move( 0, 1); uarr.onclick = () => move( 0, -1); rarr.onclick = () => move( 1, 0); document.onkeydown = function(event) { switch (event.key) { case "Q": case "Home": home.onclick(); break; case "h": case "ArrowLeft": larr.onclick(); break; case "j": case "ArrowDown": darr.onclick(); break; case "k": case "ArrowUp": uarr.onclick(); break; case "l": case "ArrowRight": rarr.onclick(); break; } } </script>