JSFiddle - React, Tailwind, and code Playground
HTML
<div id="setup">
<div>
<span class="label">Rows:</span>
<input id="rows" type="text" value="4" />
</div>
<div>
<span class="label">Columns:</span>
<input id="cols" type="text" value="8" />
</div>
<div>
I recommend against any numbers above 20x20 or so. Reveal performance is poor.
</div>
<div>
<button id="updateBtn">Draw!</button>
</div>
</div>
<table id="spiral" cellspacing="0" cellpadding="0" border="0"></table>
CSS
body {
font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
}
#updateBtn {
margin: 0 100px;
width: 100px;
}
#setup>div {
width: 300px;
margin: 0 auto;
padding: 5px;
border-left: 1px solid blue;
border-right: 1px solid blue;
}
.label {
display: inline-block;
width: 196px;
margin: 0;
padding: 0;
}
input {
width: 96px;
margin: 0;
padding: 0;
text-align: right;
}
#spiral {
width: 100%;
}
#spiral td {
text-align: center;
margin: 0;
border: 1px solid black;
box-shadow: inset 0 0 3px rgba(0,0,0,0.5);
}
JavaScript
var Spiral = (function() {
var color = function (value, total) {
var v = Math.floor((1 - (value / total)) * 96) + 128;
return ("rgb(" + v + ", " + v + ", " + v + ")");
};
var draw = function ($table, rows, cols) {
var r, c, $tr, $tAry = [], curNum = 0, p = { row: 0, col: 0 }, total = (rows * cols);
var next = (function($tAry) { //call "next" with a position to get the next position.
var d = {row: 0, col: 1}, dIndex = {row: 0, col: 0};
return (function(p) {
var isBarrier = function (r, c) { return (!$tAry[r] || !$tAry[r][c] || $tAry[r][c].text() !== "-"); };
if (isBarrier(p.row + d.row, p.col + d.col)) {
d = {
row: (([0, 1, 0, -1])[(++dIndex.row) % 4]),
col: (([1, 0, -1, 0])[(++dIndex.col) % 4])
}; //will hit a barrier, turn!
}
return (isBarrier(p.row + d.row, p.col + d.col)) ?
undefined : ({ row: (p.row + d.row), col: (p.col + d.col) });
});
}($tAry));
$table.children().remove(); //clear the table.
for(r = 0; r < rows; r++) {
$tr = $("<tr />").appendTo($table); //Add the TR to the table.
$tAry.push([]); //Add a row to the table array
for(c = 0; c < cols; c++) {
$tAry[$tAry.length-1].push($("<td>-</td>").css({
height: ($table.width() / cols), width: ($table.width() / cols)
}).appendTo($tr)); //create a TD, add it to the table array and it's row.
}
}
(function f() { //All the cool kids live the slow reveal.
$tAry[p.row][p.col].hide().text(curNum).css("background-color", color(curNum++, total)).fadeIn();
if((p = next(p)) !== undefined) { //If we're not done, continue!
...