Click the sketch above to add more cells. This sketch uses the D3.js library to generate 2D voronoi cells. Link to source files.

let vcolors = [];
let vertices = [];
let sites = [];
                
let SITE_MAX_VEL = 2;
let SITE_MARKER_SIZE = 0;

let pressed = 0;



function setup() {
  createCanvas(800,800);
}

function draw(){
  background(0);
  
  moveSites();
  
  let voronoi = d3.geom.voronoi()
    .clipExtent([
      [0, 0],
      [width, height]
    ]);
  for (var i = 0; i < sites.length; i++){
    vertices[i] = [sites[i].x,sites[i].y];
  }
 

  let polygons = voronoi(vertices);
  
  stroke(255);

  // draw polygons
  for(let j=0; j<polygons.length; j++) {
    let apolygon = polygons[j];
    
    // pick a random color
    let polyColor = sites[j].c;
    fill(polyColor);
    
    beginShape();
    for(let k=0; k<apolygon.length; k++) {
      
      let v = apolygon[k];
      vertex(v[0], v[1]);
      
    }
    endShape(CLOSE);
  }
  
  var circles = vertices.slice(0);
  
  stroke(0);
  for(let i=0; i< circles.length; i++) {
    var center = circles[i];
    push();
    translate(center[0], center[1]);
    fill(0);
    ellipse(0, 0, 1.5, 1.5);
    pop();
  }  
}
 
function moveSites()
{
  for(let i=0; i<sites.length; i++)
  {
    let s = sites[i];
    s.move();
  }
}
 
function Site(x,y){
    this.x = x;
    this.y = y;
    this.c = color(random(255), random(255), random(255));
    this.vel = createVector(random(-SITE_MAX_VEL,SITE_MAX_VEL), random(-SITE_MAX_VEL,SITE_MAX_VEL));
    
    this.move = function(){
      this.x += this.vel.x;
      this.y += this.vel.y;
      if ((this.x<0) || (this.x>width)) this.vel.x *= -1;
      if ((this.y<0) || (this.y>height)) this.vel.y *= -1;
    }
  }
 
 
function mousePressed() {
  pressed = 1;
  let s = new Site(mouseX,mouseY);
  sites.push(s);
}