A brownian motion sketch that samples a black and white image and leaves a point when the sampled color is black. Link to source files.

let Trails = [];
let Samples = [];
let CSamples = [];

let pg;
let img;

function preload() {
  img = loadImage('yes.jpg');
}

function setup() {
  createCanvas(800, 800);
  for(let i = 0; i < 15; i++){
    append(Trails,new Brownian());
  }
  noStroke();
  
  pg = createGraphics(width, height);
}

function draw() {
  background(0);
  
  pg.image(img, 0, 0);
  for(let i = 0; i < Trails.length; i++){
    let tr = Trails[i];
    tr.update();
    tr.display();
  }
  
  for(let i = 0; i < Samples.length; i++){
     let p = Samples[i];
     fill(CSamples[i]);
     ellipse(p.x,p.y,20,20);
  }
  
}


class Brownian {
  constructor() {
    this.bx = random(25,width-25);
    this.by = height/2;
    this.x = this.bx;
    this.y = this.by;
    this.damping = 0.9;
    this.k = 0.2;
    this.mass = 7.8;
    this.velx = 0.0;   // X Velocity
    this.vely = 0.0;   // Y Velocity
    this.accel = 0;    // Acceleration
    this.force = 0;
    
    this.lifespan = 0;
    
    this.pos = [];
    this.a = [];
    this.s = [];
    this.c = [];
    
    
    append(this.pos, createVector(this.x, this.y));
    append(this.a, 255);
    append(this.s, 20);
  
    append(this.c,color(random(255),random(255),random(255)));
  }
  
  update(){
    let newpx = random(-25,25);
    let newpy = random(-25,25);
  
    if(this.bx + newpx > width-25 || this.bx + newpx < 25){
      newpx = -newpx;
    }
  
    if(this.by + newpy > height-25 || this.by + newpy < 25){
      newpy = -newpy;
    }
    
    this.bx = this.bx + newpx
    this.by = this.by + newpy;
    
    this.force = -this.k * (this.y - this.by);  // f=-ky
    this.accel = this.force / this.mass;// Set the acceleration, f=ma == a=f/m
    this.vely = this.damping * this.vely + this.accel;// Set the velocity
    this.y = this.y + this.vely;// Updated position
  
    this.force = -this.k * (this.x - this.bx);// f=-ky
    this.accel = this.force / this.mass;// Set the acceleration, f=ma == a=f/m
    this.velx = this.damping * this.velx + this.accel;// Set the velocity
    this.x = this.x + this.velx;   
    
    
    let newR = red(this.c[this.c.length-1]) + random(-8,8);
    let newG = green(this.c[this.c.length-1]) + random(-8,8);
    let newB = blue(this.c[this.c.length-1]) + random(-8,8);
    
    if(this.lifespan < 130){
      append(this.pos, createVector(this.x, this.y));
      append(this.a, 255);
      append(this.s, 20);
      append(this.c,color(newR,newG,newB));
    }
      
    

    if(this.pos.length > 300){
      this.pos.splice(0,1);
      this.a.splice(0,1);
      this.s.splice(0,1);
      this.c.splice(0,1);
    }
    
    
  }
  
  display(){
    
    for(let i = 0; i < this.pos.length; i++){
     let pt = this.pos[i];
     fill(red(this.c[i]),green(this.c[i]),blue(this.c[i]),this.a[i]);
     ellipse(pt.x, pt.y, this.s[i] , this.s[i] );
     this.a[i] -= 1;
     this.s[i] = this.s[i] * 0.98;
      
    }
    let pt = this.pos[this.pos.length-1];
    let cs = pg.get(pt.x,pt.y);
    let cr = this.c[this.c.length-1];
      if(red(cs) < 100 && this.lifespan < 130){
        append(Samples, createVector(this.x, this.y));
        append(CSamples, cr);
        this.lifespan++;
      }

    noStroke();
    
  }
  
  
}