JSFiddle - React, Tailwind, and code Playground

binary keyboard experiment

by Travis Almand

HTML

<div id="entry">
  <input type="text" value="The quick brown fox jumps over the lazy dog" />
  <div>
    <button>start</button>
    <label><input type="checkbox" /> Hard</label>
  </div>
</div>

<div id="characters"></div>

SCSS

html { box-sizing: border-box; }
*, *:before, *:after { box-sizing: inherit; }

html,
body {
  margin: 0;
  padding: 0;
}

body {
  &:not(.ready) {
    #score,
    #characters {
      display: none;
    }
  }
  &.hard {
    #characters .output span {
      opacity: 0;
    }
  }
}

#entry {
  border: 1px solid black;
  margin: 10px;
  padding: 10px;

  input[type=text] {
    display: block;
    margin-bottom: 10px;
    width: 100%;
  }
  div {
    display: flex;
    
    button {
      flex-grow: 1;
    }
    label {
      flex-basis: 100px;
    }
  }
}

#characters {
  border: 1px solid black;
  margin: 10px;
  
  .character {
    border: 1px solid black;
    display: inline-block;
    margin: 4px;
    text-align: center;
    transition: all 0.5s;
    
    &.wrong {
      background-color: red;
    }
    &.correct {
      background-color: green;
    }
    
    .input {
      background-color: white;
      border: 1px solid black;
      line-height: 100%;
      margin: 4px;
      padding: 4px;
    }
    
    .output {
      background-color: white;
      border: 1px solid black;
      line-height: 100%;
      margin: 4px;
      padding: 4px;
      
      span {
        opacity: 0.25;
        transition: all 0.5s;
        
        &.correct {
          color: green;
          opacity: 1;
        }
        &.wrong {
          color: red;
          opacity: 1;
        }
      }
    }
  }
}

JavaScript

const $entryInput = document.querySelector('#entry input');
const $startBtn = document.querySelector('#entry button');
const $chars = document.querySelector('#characters');
const $hardCheck = document.querySelector('#entry label input');
let $binaries;
let count;
let numCorrect = 0;
let numWrong = 0;

document.body.addEventListener('keyup', function (e) {
  let regexp = /(^ArrowLeft$)|(^ArrowRight$)/g;
  let key;
  
  if (e.key.match(regexp)) {
    key = e.key.match(regexp)[0];
  } else {
    return false;
  }
  
  if (key) {
  	window[key]();
  }
});

$entryInput.addEventListener('input', function () {
  document.body.classList.remove('ready');
});

$startBtn.addEventListener('click', start);

$hardCheck.addEventListener('change', function () {
    this.checked ? document.body.classList.add('hard') : document.body.classList.remove('hard');
});

function ArrowLeft () {
  const $current = $binaries[count];
  $current.innerText === '0' ? check($current, 'correct') : check($current, 'wrong');
}

function ArrowRight () {
  const $current = $binaries[count];
  $current.innerText === '1' ? check($current, 'correct') : check($current, 'wrong');
}

function check ($current, which) {
  let $parent = $current.parentElement.parentElement;
  
  if (which === 'correct') {
    $current.classList.add('correct');
    
    if (!$current.nextSibling && !$parent.classList.contains('wrong')) {
      $parent.classList.add('correct');
    }
  } else {
    $current.classList.add('wrong');
    $parent.classList.add('wrong');
  }
  count++;
}

function start () {
  let text = $entryInput.value;
  let html = '';
	
  count = 0;
  document.body.classList.add('ready');
  for (let i = 0; i < text.length; i++) {
    html += buildCharacter(text[i]);
  }
  $chars.innerHTML = html;
  $binaries = document.querySelectorAll('.output span');
}

function buildCharacter (char) {
  const code = char.charCodeAt(0).toString(2);
  let template = '<div class="character"><div class="input">' + char +...