JSFiddle - React, Tailwind, and code Playground

HTML

<button onclick="Logo.forward(10)">Move forward 10</button>
<button onclick="Logo.forward(50)">Move forward 50</button>
<button onclick="Logo.rotate(15)">Rotate Right (15 deg)</button>
<button onclick="Logo.rotate(-15)">Rotate Left (-15 deg)</button>
<button onclick="Logo.rotate(90)">Turn Right (90 deg)</button>
<button onclick="Logo.rotate(-90)">Turn Left (-90 deg)</button>
<button onclick="Logo.changeColor('red')">Color Red</button>
<button onclick="Logo.changeColor('blue')">Color Blue</button>
<button onclick="Logo.changeColor('white')">Color White</button>
<button onclick="Nyan()">NYAN!</button>
<button onclick="Logo.reset()">Reset</button>
<button onclick="alert(Logo.histLength())">History Length (debug)</button>

<canvas width="500" height="500" id="drawSurface"></canvas>

    
<img id="cat" style="display: none;" src=...

CSS

#drawSurface {
    margin: 10px;
    box-shadow: 0 0 5px;   
}

#cat {
    width: 49px;
    height: 32px;
    background-repeat: no-repeat;

}

JavaScript

window.Logo = (function(fps, canvasId, catId) {
    var catImg = document.getElementById(catId),
        canvas = document.getElementById(canvasId),
        ctx = canvas.getContext('2d'),
        delay = 1000 / fps,
        history = [],
        queue = []
    ;
    
    var draw = function () {
        var i, next, lastHist;
        
        ctx.fillColor = "black";
        ctx.strokeStyle = "white";
        ctx.fillRect(0, 0, canvas.width, canvas.height);   
        if(queue.length > 0) { //pop next step from queue
            next = queue.splice(0, 1)[0];
            lastHist = history[history.length - 1];
            if(!lastHist || next.type !== lastHist.type) {
                history.push(next);
            } else {
                if(next.type === "changeColor") {
                    lastHist.val = next.val;
                } else { 
                    lastHist.val += next.val; 
                }
            }                
        }
        ctx.save();
        ctx.lineWidth = 4;
        ctx.translate(250, 250);
        ctx.beginPath();
        ctx.moveTo(0, 0);
        for(i=0; i<history.length; i++) { //play back history
            draw_fns[history[i].type](history[i].val);
        }
        ctx.stroke();  
        ctx.drawImage(catImg, 0, -9); //draw Nayncat.
        ctx.restore();
        setTimeout(draw, delay);
    };
    
    var forward = function (dist, speed) {
        speed = speed || 1;
        var i, dir = (dist >= 0) ? speed : -speed;
        
        for(i=0; i<Math.abs(dist); i+=speed) {
            queue.push({
                type: "forward",
                val: dir
            });             
        }
    };
    
    var draw_fns = {
        rotate: (function(val) { 
            ctx.rotate(val, 0); 
        }),
        forward: (function(val) {
            ctx.lineTo(val, 0);
            ctx.translate(val, 0);
        }),
        changeColor: (function(val) {
            ctx.stroke();
            ctx.beginPath();
           ...