SOURCE

// var renderer = new PIXI.
var stage = new PIXI.Container();
var renderer = new PIXI.autoDetectRenderer(innerWidth, innerHeight, {
  antialias: false
});


renderer.backgroundColor = 0x505050;
document.body.appendChild(renderer.view);


var GRID_SIZE = 3;
var CELLS_X = innerWidth / GRID_SIZE;
var CELLS_Y = innerHeight / GRID_SIZE;
var MIN_LINE_THICKNESS = 1;
var MAX_LINE_THICKNESS = 6;
var jitter = 0.75;
var grid = [];
for (var x = 0; x < CELLS_X; x++) {
  grid.push([]);
  for (var y = 0; y < CELLS_Y; y++) {
    var gXY = {};

    grid[x][y] = gXY;
    gXY.ref = {
      x: x,
      y: y
    };
    gXY.time = Number.MAX_SAFE_INTEGER;

    gXY.x = GRID_SIZE * (x + Math.random() * jitter);
    gXY.y = GRID_SIZE * (y + Math.random() * jitter);


  }
}

function rgbToHex(c, coef) {
  if (isNaN(coef)) coef = 1;
  c.r = Math.min(1, c.r);
  c.g = Math.min(1, c.g);
  c.b = Math.min(1, c.b);
  return Math.floor(c.r * 0xff * coef) * 0x10000 + Math.floor(c.g * 0xff * coef) * 0x100 + Math.floor(c.b * 0xff * coef);
}
var colors = [];

function neighbors(orig) {
  var neighbors = [];
  var ref = orig.ref;
  for (var xo = -1; xo <= 1; xo++) {
    for (var yo = -1; yo <= 1; yo++) {
      if (xo == 0 && yo == 0) continue;

      var gX = grid[ref.x + xo]
      if (!gX) continue;
      var target = gX[ref.y + yo];
      if (!target) continue;
      neighbors.push(target);
    }
  }
  return neighbors;
}



var prev = 0;

var Wanderer = function(p) {
  this.init(p);
}

function randColor() {
  return {
    r: Math.random(),
    g: Math.random(),
    b: Math.random()
  };
}

Wanderer.prototype.init = function(p) {


  this.color = randColor();
  if (p) {
    this.head = p;
  } else this.head = getRandomTarget();
  this.head.time = window.uTime;
};

Wanderer.prototype.update = function() {
  var candidates = neighbors(this.head);
  var newCandidates = [];
  for (var i = 0; i < candidates.length; i++) {
    var time = Number.MAX_SAFE_INTEGER == candidates[i].time;
    if (time) {
      candidates[i].time = this.head.time + 1;
      newCandidates.push(candidates[i]);
    }
  }
  this.prev = this.head;
  this.head = newCandidates[Math.random() * newCandidates.length >> 0];
  var otherHead = newCandidates[Math.random() * newCandidates.length >> 0];

  if (!this.head) {
    this.toDispose = true;
  } else {

    leaf.lineStyle(MIN_LINE_THICKNESS + Math.pow(MAX_LINE_THICKNESS, 1 - window.uTime / 40),
      rgbToHex(this.color, 1)); //(1-(window.uTime%30+0.2*Math.random())/30)));

    if (Math.random() < 0.5) {
      var w = new Wanderer(otherHead);
      w.color = {
        r: this.color.r * (0.97 + 0.05 * Math.random()),
        g: this.color.g * (0.97 + 0.05 * Math.random()),
        b: this.color.b * (0.97 + 0.05 * Math.random())
      };
      wanderers.push(w);
      leaf.moveTo(this.prev.x, this.prev.y);
      leaf.lineTo(otherHead.x, otherHead.y);
    }
    leaf.moveTo(this.prev.x, this.prev.y);
    leaf.lineTo(this.head.x, this.head.y);
  }

};

function getRandomTarget() {
  return grid[Math.random() * CELLS_X >> 0][Math.random() * CELLS_Y >> 0];
}

var candidates;

window.uTime = 0;
var wanderers = [];
var newWanderers = [];
wanderers.push(new Wanderer(grid[CELLS_X / 2 >> 0][CELLS_Y / 2 >> 0]));
var starters = Math.pow(Math.random(), 5) * 20;
for (var i = 0; i < starters; i++) {
  wanderers.push(new Wanderer());
}

function update(time) {

  window.uTime++;

  prev = time;
  requestAnimationFrame(update);
  console.log("running", wanderers.length, "wanderers");
  for (var n = 0; n < wanderers.length; n++) {
    wanderers[n].update();
    if (!wanderers[n].toDispose) newWanderers.push(wanderers[n]);
    else {}
  }

  wanderers = newWanderers;
  newWanderers = [];

  renderer.render(stage);
}
var leaf = new PIXI.Graphics();
stage.addChild(leaf);


document.body.addEventListener('mousedown', reset);


function reset() {
  leaf.clear();
  stage.removeChild(leaf);
  leaf = new PIXI.Graphics();
  stage.addChild(leaf);
  for (var x = 0; x < CELLS_X; x++) {
    for (var y = 0; y < CELLS_Y; y++) {

      grid[x][y].time = Number.MAX_SAFE_INTEGER;
    }

  }

  window.uTime = 0;
  wanderers = [];
  newWanderers = [];
  wanderers.push(new Wanderer(grid[CELLS_X / 2 >> 0][CELLS_Y / 2 >> 0]));
  var starters = Math.pow(Math.random(), 5) * 20;
  for (var i = 0; i < starters; i++) {
    wanderers.push(new Wanderer());
  }
}
update(0);
canvas {
  position: fixed;
  top: 0;
  left: 0;
}
console 命令行工具 X clear

                    
>
console