JSFiddle - React, Tailwind, and code Playground

by bgmort

HTML

<div id="container">
    <h1>Touch Typing Practice Keyboard</h1>
    <p>Use the on screen keyboard to help keep your eyes off your hands. If nothing happens when you type, click the screen first.</p>
    <div id="hud">Type away!</div>
    <div id="keyboard"></div>
</div>

CSS

body, html {
    font-family: 'Lucida Grande', arial, sans-serif;
 /*   background: white;*/
}
#container {
    width: 1130px;
    margin: auto;
}
#hud {
    font-size: 40px;
    background: #333;
    color: white;
    font-weight: bold;
    text-align: center;
    border-radius: 12px;
    height: 60px;
    line-height: 60px;
    margin: .5em 0;
}
#keyboard {
    width: 650px;
    height: 350px;
    /* border: 1px solid #555; */
    position: relative;
}
#keyboard .key {
    background: white;
    position: absolute;
    width: 77px; height: 77px;
    font-size: 32px;
    line-height: 77px;
    text-align: center;
    border: 1px solid #888;
    border-radius: 4px;
    padding: 0px;
    box-sizing: border-box;
}

#keyboard .key .uc, #keyboard.shift .key .lc {
    display: none;
}
#keyboard.shift .key .uc, #keyboard .key .lc {
    display: initial;
}

#keyboard .key.homerow {
    background: #eeeeee;
}

#keyboard .key.pressed {
    background: #ffffd0;
}

JavaScript

var keyboardLayout = ['1234567890-=', 'qwertyuiop[]\\', 'asdfghjkl;\'', 'zxcvbnm,./'];

var shiftKeyboardLayout = ['!@#$%^&*()_+', 'QWERTYUIOP{}|', 'ASDFGHJKL:"', 'ZXCVBNM<>?'];

var K = 1.7;
var KEY_SPACING_X = 50, KEY_SPACING_Y = 50, ROW_OFFSET_LEFT = 20;

var KEY_SPACE = 32, KEY_SHIFT = 16, KEY_BACKSPACE = 8, KEY_ENTER = 13;

var keyboard = $('#keyboard')
var hud = $('#hud')
var keyMap = {};

for (var r = 0; r < keyboardLayout.length; r++) {
    var row = keyboardLayout[r];
    for (var k = 0; k < row.length; k++) {
        var key = row[k];
        var shiftKey = shiftKeyboardLayout[r][k];
        
        var top = r * KEY_SPACING_Y;
        var left = r * ROW_OFFSET_LEFT + k * KEY_SPACING_X;

        createKey(key, shiftKey, top, left);
    }
}

var homeRow = 'asdfjkl;';
for (var i = 0; i < homeRow.length; i++) {
    keyMap[homeRow[i]].addClass('homerow');
}

createKey(' ', ' ', r * KEY_SPACING_Y, (r - 1) * ROW_OFFSET_LEFT + KEY_SPACING_X * 2);

keyMap[' '].css('width', KEY_SPACING_X * 5 * K - 8);//addClass('spacebar');

function createKey(key, shiftKey, top, left) {
    var keyEl = $('<div>').addClass('key');
    keyEl.css({
        top: top * K,
        left: left * K
    });
    
    var text = $('<span>').addClass('lc').text(key);
    var shiftText = $('<span>').addClass('uc').text(shiftKey);
    
    keyEl.append(text);
    keyEl.append(shiftText);
    
    keyboard.append(keyEl)
    
    keyMap[key] = keyMap[shiftKey] = keyEl;
}

$(document).on('keydown keyup', function(e) {
    //console.log('key event', e.keyCode)
    if (e.keyCode == KEY_SHIFT) {
        shift(e.type == 'keydown')
    }
    else if (e.type == 'keydown') {
        if (e.keyCode == KEY_BACKSPACE) {
            word = word.slice(0, -1);
            hud.text(word)
            return false
        }
        if (e.keyCode == KEY_SPACE || e.keyCode == KEY_ENTER) {
            //prevent scrolling
            type(' ');
            return false
        }
    }
	 else if (e.type == 'keyup')...