JSFiddle - React, Tailwind, and code Playground

by Josh Pullen

HTML

<div id="time"><span id="hour"></span><span id="colon">:</span><span id="minute"></span></div>

<canvas id="canvas"></canvas>
<span id="score"></span>

CSS

@import url(http://fonts.googleapis.com/css?family=Press+Start+2P);

* {
    margin:0px;
    padding:0px;
}
html, body {
    width:100%;
    height:100%;
    margin:0px;
    padding:0px;
    overflow-x:hidden;
    overflow-y:hidden;
    
    background: #148ff5;
    background: -webkit-gradient(linear, 0 0, 0 100%, from(#148ff5), to(#137bd1));
    background: -webkit-linear-gradient(#148ff5 0%, #137bd1 100%);
    background: -moz-linear-gradient(#148ff5 0%, #137bd1 100%);
    background: -o-linear-gradient(#148ff5 0%, #137bd1 100%);
    background: linear-gradient(#148ff5 0%, #137bd1 100%);
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#148ff5', endColorstr='#137bd1',GradientType=0 );
}
#time {
    color:white;
    font-size:16em;
    font-family: 'Press Start 2P', cursive;
    text-shadow:1px 1px 0px #bbb,
                2px 2px 0px #bbb,
                3px 3px 0px #bbb,
                4px 4px 0px #bbb,
                5px 5px 0px #bbb,
                6px 6px 0px #bbb,
                7px 7px 0px #bbb,
                8px 8px 0px #bbb,
                9px 9px 0px #bbb,
                10px 10px 0px #bbb;
    display: block;
    width:100%;
    text-align:center;
    margin-top:-112px;
    position:fixed;
    top:50%;
}
/* Snake */
#canvas {
    position: absolute; 
    top: 0px;
    left: 0px;
}
#score {
    position:fixed;
    top:10px;
    left:10px;
    z-index:9999;
    font-family:"Press Start 2P", sans-serif;
    font-size:14px;
    text-align:center;
    width:default;
}
#score.gameOver {
    width:100%;
    top:50%;
    margin-top:-7px;
}

JavaScript

//CLOCK
var date;
function zeroPad(i) {
    if (i < 10) {
        i = "0" + i;
    }
    return i;
}
function updateTime() {
    date = new Date();
    document.getElementById("hour").innerHTML = (date.getHours() - 1) % 12 + 1;
    document.getElementById("minute").innerHTML = zeroPad(date.getMinutes());
}
setInterval(function(){updateTime()}, 500);

//SNAKE
function _konami_() {
    //Score reset position (no class)
    document.getElementById("score").className = "";
    
    //canvas setup
    canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
    ctx.canvas.width  = window.innerWidth;
    ctx.canvas.height = window.innerHeight;
    
    //Constants (settings)
    updateSpeed = 50;
    gridSize = 16;
    snakeColor = "#000000";
    foodColor = "#333333";
    scoreColor = "#000000";
    
    //var setup
    headX = 0;
    headY = 0;
    snakeDir = 1;
    gridWidth = Math.floor(canvas.width / gridSize);
    gridHeight = Math.floor(canvas.height / gridSize);
    snakePoints = []; //All the points other than the head
    foodPoints = []; //All the food grid points
    snakeLength = 15; //The length that the snake is supposed to be
    frameTurned = false; //Prevents turning more than one time with each iteration of the game loop (snake moves before you can turn again)
    score = 0;
    alive = true;
    
    // Spawn some food
    spawnFood();
    spawnFood();
    spawnFood();
    
    //start game loop
    screenUpdate();
}
function screenUpdate () {
    //Update width and height of canvas
    ctx.canvas.width  = window.innerWidth;
    ctx.canvas.height = window.innerHeight;
    gridHeight = Math.floor(canvas.height / gridSize);
    gridWidth = Math.floor(canvas.width / gridSize);
    
    //Move snake
    move(snakeDir);
    
    //Food sensing
    for (var i=0; i<foodPoints.length; i++) {
        if(foodPoints[i][0] == headX && foodPoints[i][1] == headY) {
            foodPoints.splice(i, 1);
            snakeLength = snakeLength +...