HD44780 Char Generator

HD44780 character generator with preview

by nynexman4464

HTML

<meta name="color-scheme" content="dark light">

<div class="column">
  <div id="inputs">

  </div>
  <div id="options">
    <button id="invert">Invert</button>
    <button id="clear">Clear</button>
    <button id="save">Save</button>
  </div>
</div>
<div id="output" class="column">
</div>
<div id="code" class="column">
  <textarea id="bits"></textarea>
  <button id="edit">
    Edit
  </button>
</div>

CSS

@media (prefers-color-scheme: dark) {
  body {
    background-color: black;
    color: #ccc;
  }
}

body {
  display: grid;
  grid-template-areas:
    "inputs output code";
}

#inputs {
  margin-bottom: 1em;
}
#bits{
  height: 100%;
}
.column{
  display: flex;
  flex-direction: column;
}
.column canvas {
    align-self: center;
    margin-bottom: 1em;
}

JavaScript

const height = 8;
const width = 5;
let bits = [];
const bank = [];
let current = 0;

function initGrid() {
  bits = [];
  bank.push(bits);
  const canvas = document.createElement('canvas');
  canvas.id = `preview${current}`;
  canvas.dataset.id = current;
  const output = document.getElementById("output");
  output.insertBefore(canvas, output.firstChild);
  // double height & width to make more visible 
  // and add some margin
  canvas.height = height * 2 + 4;
  canvas.width = width * 2 + 4;
  for (let y = 0; y < height; y++) {
    const row = document.createElement("div");
    row.className = "row";
    document.getElementById("inputs").appendChild(row);
    bits.push(new Array(width).fill(false));
    for (let x = 0; x < width; x++) {
      const check = document.createElement("input");
      check.type = "checkbox";
      check.dataset.x = x;
      check.dataset.y = y;
      row.appendChild(check);
    }
  }
  updateAll();
}

function init() {
  initGrid();
  document.getElementById("inputs").addEventListener("click", (event) => {
    if (event.target.tagName !== "INPUT") {
      return;
    }
    const data = event.target.dataset;
    bits[data.y][data.x] = event.target.checked;
    updateAll();
  });
  document.getElementById("clear").addEventListener("click", () => toggleCells(true));
  document.getElementById("invert").addEventListener("click", () => toggleCells(false));
  document.getElementById("save").addEventListener("click", save);
  document.getElementById("edit").addEventListener("click", () => {
    parse();
  });
}

function toggleCells(clear) {
  const checkboxes = document.getElementsByTagName("input");
  [...checkboxes].forEach(checkbox => {
    if (clear) {
      checkbox.checked = false;
    } else {
      checkbox.checked = !checkbox.checked;
    }
    const data = checkbox.dataset;
    bits[data.y][data.x] = checkbox.checked;
  });
  updateAll();
}

function updateCanvas() {
  const canvas = document.getElementById(`preview${current}`);
 ...