let canvasHeight = 500
let row
let grid
let amtOfHorizontalCircles = 15
let linesAmt = 50
let ySpacing = 10
let lineSpacing = canvasHeight/linesAmt
let circleMaxWidth = 10

const createCircle = (fillColor, x, y, maxRadius) => {
let xpos = x
let ypos = y
 return {
   xpos,
   ypos,
   display() {
     noStroke()
     fill(fillColor)
     ellipse(xpos, ypos, maxRadius, maxRadius)
   },
   slide(amt) {
     if( ypos >  linesAmt * lineSpacing ) {
       maxRadius = Math.random() * circleMaxWidth
       ypos = lineSpacing
     }
     ypos += amt
   },
 }
}

const createLine = (arr, amt, startingPoint, y) => {
  if( arr.length < amt) {
     arr.push(createCircle(`rgba(205, 64, 24, ${Math.random().toFixed(1)})`, startingPoint,  y, Math.random()*9))
     createLine(arr, amt, startingPoint += width/amtOfHorizontalCircles, y)
  }
  return arr
}


const createGrid = (arr, linesAmt, y) => {
  if( arr.length < linesAmt) {
    arr.push(createLine([], amtOfHorizontalCircles, 0, y))
    createGrid(arr, linesAmt, y += lineSpacing)} 
  return arr
}

const slideRow = () => {
  // shits heights, and moves y's to begginig of they are higher tha Height
  grid.forEach( (line) => {
    line.forEach( x => {
    x.slide(ySpacing)
    })
  })
}

function setup () {
  createCanvas(300, canvasHeight)
  background("#140c28")
  grid = createGrid([], linesAmt, lineSpacing)
  setInterval(slideRow, 500)
}

function draw () {
  background("#140c28")
  grid.forEach( row => {
    row.forEach( x => {
      x.display()
    })
  })
}
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js