JSFiddle - React, Tailwind, and code Playground

by Josh Pullen

HTML

<input type="number" id="input" placeholder="Enter a number...">
<canvas id="output"></canvas>
<img src="http://joshuapullen.com/files/quipu/1.png" id="img-1">
<img src="http://joshuapullen.com/files/quipu/2.png" id="img-2">
<img src="http://joshuapullen.com/files/quipu/3.png" id="img-3">
<img src="http://joshuapullen.com/files/quipu/4.png" id="img-4">
<img src="http://joshuapullen.com/files/quipu/5.png" id="img-5">
<img src="http://joshuapullen.com/files/quipu/6.png" id="img-6">
<img src="http://joshuapullen.com/files/quipu/7.png" id="img-7">
<img src="http://joshuapullen.com/files/quipu/8.png" id="img-8">
<img src="http://joshuapullen.com/files/quipu/9.png" id="img-9">
<img src="http://joshuapullen.com/files/quipu/E.png" id="img-E">
<img src="http://joshuapullen.com/files/quipu/space.png" id="img-space">

CSS

body {
    background:#181818;
    margin:0;
}
img {
    display:none;
}
#input {
    position:fixed;
    bottom:20px;
    left:20px;
    background:transparent;
    border:none;
    outline:none;
    border-bottom:2px solid #555;
    color:#555;
    font-size:48px;
}

#input::placeholder { color:#555; }
#input::-webkit-input-placeholder { color:#555; }
#input::-moz-placeholder { color:#555; }
#input:-ms-input-placeholder { color:#555; }
#input:-moz-placeholder { color:#555; }

#output {
    float:right;
    margin-right:100px;
}

JavaScript

var input = document.getElementById("input");
var canvas = document.getElementById("output"),
	ctx = canvas.getContext("2d");

input.addEventListener("keydown", updateRope);
input.addEventListener("keyup", updateRope);
input.addEventListener("change", updateRope);

function updateRope() {
	function getImg(id) {
        if(id === "S") id = "1";
        if(id === " ") id = "space";
        return document.getElementById("img-" + id);
    }
    
    if(input.value < 0) input.value = 0;
    if(String(input.value).length > 20) {
    	alert("Very funny.");
    	input.value = 0;
    }
    
    // Turn number to rope string
    var ropeString = numToRope(input.value);
    
    // Set canvas dimensions (and clear)
	var height = 0;
    for(i = 0; i < ropeString.length; i++) {
    	height += getImg(ropeString[i]).height;
    }
	canvas.width = 54;
    canvas.height = height;
    
    // Render rope in pieces
    if(ropeString.length > 1) {
        var y = 0;
        for(i = 0; i < ropeString.length; i++) {
            var img = getImg(ropeString[i]);
            ctx.drawImage(img, 0, y);
            y += img.height;
        }
    }
};

function numToRope(num){
	var rope = " ";
    num = String(num);
    
    for(i = 0; i < num.length; i++) {
    	if(i === num.length - 1) {
        	if(num[i] === "1") {
            	rope += "E";
            } else {
            	rope += num[i];
            }
        } else {
        	for(n = 0; n < parseInt(num[i]); n++) {
            	rope += "S";
            }
        }
        
        rope += "  ";
    }
    
    return rope;
}