Binary grid to UTF-16

Grid of binary data to UTF-16 string

by fxi

HTML

<div class="container">
  <h3>Binary to UTF-16 explorer</h3>
  <small>Explore UTF-16 world by clicking on stuff. Yep. And use it to golf code or something...</small>
  <ul>
  <li>Click on checkboxes to produce UTF-16 strings from binary </li>
  <li> Checked = 1, unchecked = 0 </li>
  <li>The result is shown in the gray box</li>
    <li>Empty lines are ignored (for now) </li>
    <li>May produce weird or invisible characters</li>
    <li>Click on <a id="link" href=# target="_blank">this link</a> to see it in tixy.land</li>
  </ul>
  <pre id="out" class="result"></pre>
  <div id="grid"></div>
</div>

CSS

html,
body {
  font-family: sans-serif;
}

.container {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.result {
  color: #fff;
  width: 100%;
  border-radius: 5px;
  background: #474747;
  min-height: 1.5em;
  max-height: 1.5em;
  overflow: hidden;
  padding: 5px;
  font-size: 1.5em;
}

JavaScript

class Grid {
  constructor(opt) {
    this.opt = opt;

    this.init();
  }

  init() {
    let ui = "";
    const grid = this;
    if (grid._init) {
      return;
    }
    grid.elGrid = grid.opt.elGrid;
    grid.elOut = grid.opt.elOut;
    grid.elLink = grid.opt.elLink;
    grid._init = true;
    grid._size = grid.opt.nRow * grid.opt.nCol;
    grid._data = new Uint8Array(grid._size);
    grid.loop((x, y) => {
      const elCheck = grid.el('input', {
        type: 'checkbox',
        dataset: {
          x: x,
          y: y
        },
        className: 'cell'
      })
      grid.elGrid.appendChild(elCheck);
      if (x === (grid.opt.nCol - 1)) {
        grid.elGrid.appendChild(
          this.el('br')
        )
      }
    })
    grid.elGrid.addEventListener('click', grid.updateUtf.bind(grid))
  }

  el(tag, opt) {
    opt = Object.assign({}, opt);
    const el = document.createElement(tag);
    for (let o in opt) {
      const v = opt[o];
      if (v instanceof Object) {
        Object.assign(el[o], v)
      } else {
        el[o] = v;
      }
    }
    return el;
  }

  loop(cb) {
    let i = 0;
    for (let y = 0; y < this.opt.nRow; y++) {
      for (let x = 0; x < this.opt.nCol; x++) {
        cb(x, y, i++)
      }
    }
  }

  updateUtf(e) {
    const grid = this;
    const valid = e.target.classList.contains('cell');
    if (!valid) {
      return;
    }

    const p = e.target.dataset.x * 1 +
      e.target.dataset.y * grid.opt.nCol;

    const v = e.target.checked * 1;
    grid._data[p] = v;
    const col = [];
    const row = [];
    grid.loop((x, y) => {
      const p = x + y * grid.opt.nCol;
      row.push(grid._data[p]);
      if (x === grid.opt.nCol - 1) {
        if (!grid.opt.mirror) {
          row.reverse();
        }
        col.push(grid.toChar(row.join("")));
        row.length = 0;
      }
    })
    const str = col.join("");
    grid.elLink.href = grid.toTixyUrl(str);
    grid.elOut.innerText = str;
  }

  toChar(row) {
    const int =...