JSFiddle - React, Tailwind, and code Playground
CoffeeScript
window.addEventListener 'load', ->
new Spiral
rows: 4
cols: 8
colorMin: 220
colorMax: 130
initial: 0
size: 50
class Spiral
constructor: (@options) ->
@current = row: 0, col: 0
@prepareCanvas()
@prepareCells()
@fill()
prepareCanvas: ->
@canvas = document.createElement 'canvas'
@context = @canvas.getContext '2d'
@canvas.width = @options.cols * @options.size
@canvas.height = @options.rows * @options.size
document.body.appendChild @canvas
prepareCells: ->
@cells = []
for row in [0...@options.rows]
for col in [0...@options.cols]
@cells[row] = [] if !@cells[row]
@cells[row][col] = new Cell(row, col, @options.size, @context)
fill: ->
total = @options.initial + @options.rows * @options.cols
for i in [@options.initial...total]
cell = @next()
cell.draw i, @color(i, total)
next: ->
switch @direction
when 'right'
if @checkCell(@current.row, @current.col + 1)
@current.col += 1
else
@direction = 'down'
return @next()
when 'down'
if @checkCell(@current.row + 1, @current.col)
@current.row += 1
else
@direction = 'left'
return @next()
when 'left'
if @checkCell(@current.row, @current.col - 1)
@current.col -= 1
else
@direction = 'up'
return @next()
when 'up'
if @checkCell(@current.row - 1, @current.col)
@current.row -= 1
else
@direction = 'right'
return @next()
else
@direction = 'right'
@cells[@current.row][@current.col]
checkCell: (row, col) ->
@cells[row] && @cells[row][col] && !@cells[row][col].drawn
color: (i, total) ->
colorDiff = @options.colorMin - @options.colorMax
percentage = (i - @options.initial) / (total - @options.initial)
Math.floor @options.colorMin - colorDiff * percentage
class Cell
...