Lenticular Animation: Flowing circles

I was inspired for this design by caustics. I had made something similar in a previous semester so I piggy-backed off of that code, but remade it so that it flowed using sine waves rather than with noise. I also made it loop. I feel that I could have worked much longer on the different ways of making the circles scale, but I am nonetheless pleased with my results. For me it has a calming feel. The thing I feel I failed most at with this project was time consumption. I spent a long time trying to figure out some intricate system to animate, when in the end I wound up going with something simple. This is mostly because I fell back to researching, and I looked at the Bees and Bombs website. The interesting animations with simple geometry were very impressive, and it reminded me of a (less impressive than theirs) work that I had done which may be adaptable.

flow_small

/////////////////////////
// Flowing
// Author: Matt Kellogg
// Created: September 22, 2014
// Edited: February 10, 2015 added saving images and use of sin wave
/////////////////////////

//declare globals/constants
var backgroundColor, diam;
var img;
var counter;
var SAVE_IMAGE = false;

function setup() {
  createCanvas(1500,1500);
	img = createGraphics(1500,1500);
	// Similar to additive color blending which wasn't working
  img.blendMode(DODGE);
  // a deep red
  backgroundColor = color(125,20,20);
  diam = 90.0;
	counter = 0;
	if (SAVE_IMAGE){
	for (counter = 0; counter< 10; counter++){
		drawImage(counter);
		save(img, "gif-image-"+counter+".png");
	}
	}
}

function drawImage(counter){
	  //declare variables so they aren't re-instantiated per loop
  var r, b, d, x2, y2, x, y, xDif;
  // The distance to the next circle at the same height
  xDif = 2*diam*cos(radians(30));
	img.blendMode(NORMAL);
  img.background(backgroundColor);
	img.blendMode(DODGE);
  img.noStroke();
  for (x = -diam; x < width+diam; x+=xDif)
  {
    for (y = -diam; y < height+ diam; y+= diam)
    {
	    //for each position draw a two circles
			// the second is down and to the right
			// so that all the circles will be tangent
			// without the size variation
			
			// map red and blue values to x and y positions
			r = map(x, 0, width, 50, 120);
			b = map(y, 0, height, 50, 120);
			img.fill(r,100,b);
			// generate noise for the first diameter based on
			// the position and the frameCount
			d = diam*(1.0+Math.sin((x+y+counter*2)*0.314))/2.0;//(Math.sin(y*frameCount*0.1)+Math.cos(x*frameCount*0.1))*diam;//noise(x*0.1, y*0.1, frameCount*0.01)*diam - diam/3.0;
			img.ellipse(x, y, diam+d, diam+d);
		
			// calculate the position for the second circle
			x2 = x + diam*Math.cos(radians(30));
			y2 = y + diam*Math.sin(radians(30));
			// get the red and blue
			r = map(x, 0, width, 50, 120);
			b = map(y, 0, height, 50, 120);
			img.fill(r,100,b);
			// make some noise
			d = diam*(1.0+Math.sin((x2+y2+counter*2)*0.314))/2.0;//(Math.sin(y*frameCount*0.1)+Math.cos(x*frameCount*0.1))*diam;//noise(x*0.1, y*0.1, frameCount*0.01)*diam-diam/3.0;
			img.ellipse(x2, y2, diam+d, diam+d);
    }
  }
}

function draw() {
	drawImage(frameCount/2);
	background(0);
	image(img,0,0);
}