JSFiddle - React, Tailwind, and code Playground

d3.js Random traversal.

by schrodingers

HTML

<script src="//d3js.org/d3.v3.min.js"></script>

CSS

body {
  background: #fff;      
  margin: 0;
  padding: 0;  
  overflow: hidden;
}

  
canvas {    
}

JavaScript

var width = 800,
  height = 600;


var N = 1 << 0,
  S = 1 << 1,
  W = 1 << 2,
  E = 1 << 3;

var cellSize = 5, // Толщина "стены"
  cellSpacing = 10, // ширина "прохода"
  cellWidth = Math.floor((width - cellSpacing) / (cellSize + cellSpacing)),
  cellHeight = Math.floor((height - cellSpacing) / (cellSize + cellSpacing)),
  cells = generateMaze(cellWidth, cellHeight), // each cell’s edge bits
  distance = 0,
  visited = new Array(cellWidth * cellHeight),
  frontier = [(cellHeight - 1) * cellWidth];

var canvas = d3.select("body").append("canvas")
  .attr("width", width)
  .attr("height", height);

var context = canvas.node().getContext("2d");

context.translate(
  Math.round((width - cellWidth * cellSize - (cellWidth + 1) * cellSpacing) / 2),
  Math.round((height - cellHeight * cellSize - (cellHeight + 1) * cellSpacing) / 2)
);

context.fillStyle = "#fff";
for (var y = 0, i = 0; y < cellHeight; ++y) {
  for (var x = 0; x < cellWidth; ++x, ++i) {
    fillCell(i);
    if (cells[i] & S) fillSouth(i);
    if (cells[i] & E) fillEast(i);
  }
}

d3.timer(function() {
  if (!(n0 = frontier.length)) return true;

  context.fillStyle = d3.hsl(distance++ % 360, 1, .5) + "";

  if (distance & 1) {
    for (var i = 0; i < n0; ++i) {
      fillCell(frontier[i]);
    }
  } else {
    var frontier1 = [],
      i0,
      i1,
      n0;

    for (var i = 0; i < n0; ++i) {
      i0 = frontier[i];
      if (cells[i0] & E && !visited[i1 = i0 + 1]) visited[i1] = true, fillEast(i0), frontier1.push(i1);
      if (cells[i0] & W && !visited[i1 = i0 - 1]) visited[i1] = true, fillEast(i1), frontier1.push(i1);
      if (cells[i0] & S && !visited[i1 = i0 + cellWidth]) visited[i1] = true, fillSouth(i0), frontier1.push(i1);
      if (cells[i0] & N && !visited[i1 = i0 - cellWidth]) visited[i1] = true, fillSouth(i1), frontier1.push(i1);
    }

    frontier = frontier1;
  }
});

function fillCell(i) {
  var x = i % cellWidth,
    y = i / cellWidth | 0;
  context.fillRect(x * cellSize + (x + 1) *...