JSFiddle - React, Tailwind, and code Playground

by schrodingers

HTML

<canvas width="320" height="240"></canvas>
<p id="count">Rectangles: 10</p>
<input id="slider" type="range" min="1" max="50" value="10" />
<br />
<label>Show Quad Tree:</label>
<input id="showTree" type="checkbox" checked />
<br />
<p id="checks">Checks: 0</p>

CSS

body {
  background-color: #333;
  font-family: Helvetica, Arial, 'sans-serif';
  color: #FFF;
}

canvas {
  float: left;
  margin-right: 4px;
  background-color: #FFF;
}

JavaScript

/* QuadTree collision detection on canvas */

var canvas = document.querySelector('canvas'),
  context = canvas.getContext('2d'),
  colors = ['#000', '#0F0', '#00F', '#0FF', '#F0F', '#080', '#008', '#088', '#808'],
  pickedColors = [],
  lastTime = new Date(),
  minCellSize = 50,
  maxRectangles = 4,
  rootTree = new QuadTree(0, 0, canvas.width, canvas.height, 10, 4),
  isTreeVisible = true,
  checks = 0,
  rectangles = [];

function QuadTree(x, y, w, h, maxObjects, maxDepth, depth) {
  this.x = x;
  this.y = y;
  this.w = w;
  this.h = h;
  this.children = [];
  this.objects = [];

  // If a parent node was passed in, get these values from it
  if (maxObjects instanceof QuadTree) {
    var parent = maxObjects;
    this.maxObjects = parent.maxObjects;
    this.maxDepth = parent.maxDepth;
    this.depth = parent.depth + 1;
    this.parent = parent;
  } else {
    this.parent = null;
    this.maxObjects = maxObjects;
    this.maxDepth = maxDepth;
    this.depth = depth || 0;
  }
}

QuadTree.prototype.insert = function(obj) {
  // Only insert if we're at max depth or we can add objects
  var atMaxDepth = (this.depth >= this.maxDepth);
  var noChildren = (this.children.length === 0);
  var canAddMore = (this.objects.length < this.maxObjects);
  if (atMaxDepth || (noChildren && canAddMore)) {
    this.objects.push(obj);
  } else if (this.children.length) {
    // Insert the object into the correct children
    for (var i = 0; i < 4; i++) {
      var child = this.children[i];
      if (isColliding(child, obj)) {
        child.insert(obj);
      }
    }
  } else {
    // Split into quadrants
    var halfWidth = this.w / 2;
    var halfHeight = this.h / 2;
    var top = this.y;
    var bottom = this.y + halfHeight;
    var left = this.x;
    var right = this.x + halfWidth;

    this.children.push(
      new QuadTree(right, top, halfWidth, halfHeight, this)
    );
    this.children.push(
      new QuadTree(left, top, halfWidth, halfHeight, this)
    );
   ...