initial commit

This commit is contained in:
Luca 2025-05-20 19:10:24 +02:00
commit 17e319990c
6 changed files with 167 additions and 0 deletions

5
.editorconfig Normal file
View File

@ -0,0 +1,5 @@
root = true
[*.{css,html,js,json}]
indent_style = space
indent_size = 4

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
config.json

60
app.js Normal file
View File

@ -0,0 +1,60 @@
function randInt(max) {
return Math.floor(Math.random() * max);
}
class App {
constructor() {
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", this.init);
} else {
this.init();
}
}
async init() {
this.config = await (await fetch("/config.json")).json();
const gridConfig = this.config["grid"] ?? {};
const grid = document.getElementById("grid");
const width = parseInt(gridConfig["width"] ?? 5);
if (width !== 5) {
grid.style.gridTemplateColumns = `repeat(${width}, 1fr)`;
}
const height = parseInt(gridConfig["height"] ?? 5);
if (height !== 5) {
grid.style.gridTemplateRows = `repeat(${height}, 1fr)`;
}
const phrases = this.config["phrases"] ?? [];
const probability = Math.min(phrases.length / Math.max(width * height - 1, 1), 1);
const freeTile = this.config["freeTile"] ?? false;
for (let y = 0; y < height; ++y) {
for (let x = 0; x < width; ++x) {
const tile = document.createElement("div");
tile.classList.add("tile");
if (x === 0) tile.classList.add("row-start");
if (y === 0) tile.classList.add("col-start");
if (
freeTile && freeTile.length
&& x === Math.floor(width / 2)
&& y === Math.floor(height / 2)
) {
tile.innerText = freeTile[randInt(freeTile.length)];
} else if (phrases && phrases.length && Math.random() < probability) {
const phrase = randInt(phrases.length);
tile.innerText = phrases[phrase];
phrases.splice(phrase, 1);
}
grid.append(tile);
}
}
}
}
const app = new App();

11
config.example.json Normal file
View File

@ -0,0 +1,11 @@
{
"freeTile": [
"FREE"
],
"grid": {
"height": 5,
"width": 5
},
"phrases": [
]
}

14
index.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GNOBI</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<link rel="stylesheet" href="style.css">
<script src="app.js"></script>
</head>
<body>
<main id="grid">
</main>
</body>
</html>

76
style.css Normal file
View File

@ -0,0 +1,76 @@
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
align-items: center;
display: flex;
font-family: "Maven Pro", sans-serif;
justify-content: center;
min-height: 100vh;
}
#grid {
aspect-ratio: 1 / 1;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(5, 1fr);
width: 100%;
}
.tile {
--border-width: 1px;
align-content: center;
border-color: #000;
border-style: solid;
border-width: 0 var(--border-width) var(--border-width) 0;
font-size: 12pt;
padding: 1em;
text-align: center;
}
.tile.col-start {
border-top-width: var(--border-width);
}
.tile.row-start {
border-left-width: var(--border-width);
}
@media print {
#grid {
margin: 20mm;
}
.tile {
--border-width: 1pt;
}
}
@media print and (orientation: landscape) {
body {
height: 210mm;
width: 297mm;
}
#grid {
height: calc(100% - 20mm * 2);
width: auto;
}
}
@media print and (orientation: portrait) {
body {
height: 297mm;
width: 210mm;
}
}
@media screen {
#grid {
margin: 2em;
max-width: 1000px;
}
}