JSFiddle - React, Tailwind, and code Playground

HTML

<div id="main">

    <div id="player">
        <div id="details">
            <input type="text" id="word-fun-input" placeholder="Start typing...">
            <button id="word-fun-auto">Start Display</button>
            <p><a href="http://www.andystabler.co.uk">Andy Stabler</a></p>
        </div>
        <canvas id="word-fun-canvas">Canvas not supported</canvas>
    </div>
</div>

CSS

/*
Created By Andy Stabler
*/

body {
    font-family: helvetica, sans-serif;
    font-size: 100%;
    margin: 0;
}

#main {
    margin: 0 auto;
}

#player {
    display: inline-block;
}

#details {
    position: absolute;
    margin-top: .5em;
    width: 98%;
    margin-left: .5em;
    margin-right: .5em;
}

details * {
    padding: .5em;
}

button {
    -webkit-appearance: none;
    float: left;
    background-color: #428bca;
    color: #fff;
    text-decoration: none;
    border: none;
    margin-top: .3em;
    margin-bottom: 10px;
    outline: 0;
    font-size: 1em;
    line-height: 2;
}

button:hover {
    background-color: #2C71AD;
}

#pause-toggle {
    float: left;
}

#details p {
    margin: 0;
}

#details p a {
    padding: .5em;
    line-height: 2;
    color: inherit;
    font-weight: 200;
    text-decoration: none;
    display: inline-block;
    color: white;
}

#word-fun-input {
    float: left;
    line-height: 1.5;
    font-size: 2em;
    width: 98%;
    opacity: 0.8;
}

#word-fun-canvas {
    clear: both;
    background-color: black;
}

@media only screen and (max-device-width: 400px) {

    #details {
        width: 98%;
        margin-left: 0;
        margin-right: 0;
    }

}

JavaScript

/**
 * Created By Andy Stabler
 */
var wordFun = {GRAVITY: .3};

/**
 * The animator is the main controller for the explosions
 *
 * Contains a queue of exploders (a new exploder is added when the fire event occurs. They are removed once
 *  the exploder dies)
 *
 * There must be a canvas with the id 'word-fun-canvas' - this is where the drawings will take place
 */
wordFun.animator = function () {
    "use strict";
    this.ctx = document.getElementById('word-fun-canvas').getContext('2d');
    this.initDimension();
    this.exploders = [];
    this.clearCanvas();
    this.started = false;
    this.paused = false;
};

/**
 * Sets the dimension of the canvas to the window's dimension
 */
wordFun.animator.prototype.initDimension = function () {
    "use strict";
    // set the canvas size to match the window's
    this.ctx.canvas.width = window.innerWidth;
    this.ctx.canvas.height = window.innerHeight;
    this.width = this.ctx.canvas.width;
    this.height = this.ctx.canvas.height;
};

/**
 * Add an exploder to the queue of exploders to animate
 */
wordFun.animator.prototype.pushExploder = function (exploder) {
    "use strict";
    if (this.paused)
        return;
    var that = this;
    // add the exploder to the end of the queue
    this.exploders.push(exploder);

    // check the explosion every so often - once it's finished remove it from the animation
    var t = setInterval(function () {
        if (exploder.isFinished()) {
            // remove it from queue
            that.shiftExploder();
            // stop checking to see if it's dead once we know it is
            clearInterval(t);
        }
    }, 500);

    if (!this.started) {
        this.started = true;
        this.animRequest = requestAnimationFrame(anim.explode.bind(anim));
    }
};

/**
 * Remove an exploder from the animation queue - done once an exploder has finished
 */
wordFun.animator.prototype.shiftExploder = function () {
    "use strict";
    // remove most recent exploder from...