Audio embedded, please turn up volume. Vimeo recording also included at bottom.

In our final project, we made a music video and explored the relationship between geometric motion and rhythm. We divided the video into four sections of movements, interacting with the rhythm and mood of the music.

Motion section 1: Morphing blob

Motion section 2: Droplets

Motion section 3: Interacting Balls

Motion section 4: Splitting /Pulsing Balls

```
//stores music
var song;
//intro blob variables
var dx1;
var dy1;
var v0x;
var v0y;
var v1x;
var v1y;
var v2x;
var v2y;
var v3x;
var v3y;
var v4x;
var v4y;
var v5x;
var v5y;
var vcolor = 100;
var vopac = 255;
//circle droplet variables
var diam1 = 30;
var diam2 = 30;
var diam3 = 30;
var diam4 = 30;
var opac = 200;
var drate = 6;
//interacting balls variables
var IBdiam = 30;
var IBxpos1 = 20;
var IBypos1 = 20;
var IBxpos2 = 20;
var IBypos2 = 20;
var IBxpos3 = 20;
var IBypos3 = 20;
var IBxpos4 = 20;
var IBypos4 = 20;
var IBxpos5 = 20;
var IBypos5 = 20;
var triangleOpac = 255;
//red bars variables
var bwidth1 = 15;
var bheight = 15;
var bwidth2 = 15;
var barOpac = 255;
var bspeed = 4;
var rectx1 = 200;
var rectx2 = 230;
//splitting balls variables
var SBypos = -15;
var SBxpos1 = 300;
var SBxpos2 = 300;
var ball3y = 200;
var ball4y = 200;
function preload() {
song = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/music.mp3");
song.setVolume(0.5);
}
function setup() {
createCanvas(600, 400);
frameRate(10);
song.play();
//set values to intro blob vertexes
v0x = width/2 - 70;
v0y = height/2;
v1x = width/2;
v1y = height/2 - 70;
v2x = width/2 + 70 ;
v2y = height/2 ;
v3x = width/2;
v3y = height/2 + 70;
v4x = width/2 - 70;
v4y = height/2;
v5x = width/2;
v5y = height/2 - 70;
v6x = width/2 + 70;
v6y = height/2;
}
function draw() {
angleMode(DEGREES);
background(150);
noStroke();
fill(vcolor);
vcolor += 2;
drawintroDrop(); //larger intro blob
fill(130, 130, 130, vopac);
push();
scale(0.4);
translate(2 * width/3 + 20, 2 * height/3);
drawintroDrop(); //smaller intro blob
pop();
vopac -= 10;
drawDroplets();
drawInteractballs();
pulsingBalls();
}
function interactingBalls(op, xpos, ypos) { //make interacting ball
fill(132, 190, 160, op);
ellipse(xpos, ypos, 30, 30);
}
function makeDrop(r, g, b, x, y, diam) { //make droplet
fill(r,g,b,opac);
ellipse(x, y, diam, diam);
}
function drawintroDrop(){ //intro blob
angleMode(DEGREES);
beginShape();
curveVertex(v0x, v0y);
v0x -= 2;
v0y += 4;
curveVertex(v1x, v1y);
v1x -= 2;
v1y += 6;
curveVertex(v2x, v2y);
v2x -= 8;
v2y -= 4;
curveVertex(v3x,v3y);
v3x += 2;
v3y -= 4;
curveVertex(v4x,v4y);
v4x += 8;
v4y += 4;
curveVertex(v5x, v5y);
v5x -= 2;
v5y += 6;
curveVertex(v6x, v6y);
v6x -= 2;
v6y += 4;
endShape();
}
function drawDroplets(){ //circle droplets
if(frameCount > 52){ //first droplet
makeDrop(108,163,140,width/4, height/4, diam1);
diam1 += drate;
opac -= 3;
}
if(frameCount > 62){ //second droplet
makeDrop(108,123,140,width/2, height/2 + 60, diam2);
diam2 += drate;
}
if(frameCount > 73){ //third droplet
makeDrop(178,160,140,width - 100, height - 100, diam3);
diam3 += drate;
}
if(frameCount > 88){ //fourth droplet
makeDrop(200,163,140,width - 140, height - 270, diam4);
diam4 += drate;
}
if(frameCount > 120 & frameCount % 3 == 0 ){ //flashing background
fill(252, 252, 240);
rect(0, 0, width, height);
}
}
function drawInteractballs(){ //interacting balls
if(frameCount > 120 & frameCount < 172 ){ //red triangle
fill(210, 65, 65, triangleOpac);
triangle(30, 45, 30, 135, 165,135);
}
//balls movement
if(frameCount > 120){ //ball one
interactingBalls(250, IBxpos1, IBypos1);
IBxpos1 += 6;
IBypos1 += 4;
if(IBxpos1 > 165 + IBdiam/3){
IBxpos1 -= 3;
IBypos1 += 10;
}
if(IBypos1 > 350 - IBdiam/2 || frameCount > 161){
IBxpos1 -= 1;
IBypos1 -= 20;
}
if(frameCount > 185){
IBypos1 += 12;
}
if(frameCount > 211){
IBypos1 -= 12;
}
if(frameCount > 237){
IBypos1 += 18;
}
}
if(frameCount>126.5){ //ball two
interactingBalls(180, IBxpos2, IBypos2);
IBxpos2 += 6;
IBypos2 += 4;
if(IBxpos2 > 165 + IBdiam/3){
IBxpos2 -= 3;
IBypos2 += 10;
}
if(IBypos2 > 350 - IBdiam/2 || frameCount > 167.5){
IBxpos2 -= 1;
IBypos2 -= 20;
}
if(frameCount > 191.5){
IBypos2 += 12;
}
if(frameCount > 217.5){
IBypos2 -= 12;
}
if(frameCount > 244.5){
IBypos2 += 18;
}
}
if(frameCount > 133){ //ball three
interactingBalls(130, IBxpos3, IBypos3);
IBxpos3 += 6;
IBypos3 += 4;
if(IBxpos3 > 165 + IBdiam/3){
IBxpos3 -= 3;
IBypos3 += 10;
triangleOpac -= 17; //triangle opacity decreases when third ball falls
}
if(IBypos3 > 350 - IBdiam/2 || frameCount > 174){
IBxpos3 -= 1;
IBypos3 -= 20;
}
if(frameCount > 198){
IBypos3 += 12;
}
if(frameCount > 224){
IBypos3 -= 12;
}
if(frameCount > 251){
IBypos3 += 18;
}
}
if(frameCount>139.5){ //ball four
interactingBalls(80, IBxpos4, IBypos4);
IBxpos4 += 6;
IBypos4 += 4;
if(IBxpos4 > 165 + IBdiam/3){
IBxpos4 -= 3;
IBypos4 += 10;
}
if(IBypos4 > 350 - IBdiam/2 || frameCount > 180.5){
IBxpos4 -= 1;
IBypos4 -= 20;
}
if(frameCount > 204.5){
IBypos4 += 12;
}
if(frameCount > 230.5){
IBypos4 -= 12;
}
if(frameCount > 257.5){
IBypos4 += 18;
}
}
if(frameCount>146.5){ //ball five
interactingBalls(40, IBxpos5, IBypos5);
IBxpos5 += 6;
IBypos5 += 4;
if(IBxpos5 > 165 + IBdiam/3){
IBxpos5 -= 3;
IBypos5 += 10;
}
if(IBypos5 > 350 - IBdiam/2 || frameCount > 186.5){
IBxpos5 -= 1;
IBypos5 -= 20;
}
if(frameCount > 211){
IBypos5 += 12;
}
if(frameCount > 237){
IBypos5 -= 12;
barOpac -= 7; //red bars opacity decreases on fifth balls second to last bounce
}
if(frameCount > 264){
IBypos5 += 18;
}
}
//red bars
if(frameCount > 159){ //bottom bar
fill(210, 65, 65, barOpac);
rect(rectx1,345,bwidth1,bheight);
bwidth1+= bspeed;
}
if(frameCount > 175){ //top bar
fill(210, 65, 65, barOpac);
rect(rectx2,155,bwidth2,bheight);
bwidth2 += bspeed;
}
if(bwidth1 > 350 || frameCount > 212){ //bars moving right
rectx1 += 7;
rectx2 += 2;
}
}
function pulsingBalls(){ //splitting and pulsing balls
//constraining variables
var SBy1 = constrain(SBypos, -IBdiam/2, height/2);
var SBx1 = constrain(SBxpos1, width/3 - 25, width);
var SBx2 = constrain(SBxpos2, 0, width * (2/3) + 25);
if(frameCount > 287){ //first circle moving
fill(132, 190, 160);
SBypos += 10;
ellipse(SBx1, SBy1, IBdiam, IBdiam);
ellipse(SBx2, SBy1, IBdiam, IBdiam);
if(SBy1 > 160 & SBy1 < 200){ //diam increases
IBdiam += 5;
}
if(SBy1 == 200){ //split to two circles
SBxpos1 -= 5;
SBxpos2 += 5;
if(frameCount>330){ //split to six circles
var SBy2 = constrain(ball3y, height/4, height/2);
var SBy3 = constrain(ball4y, height/2, height * (3/4));
ellipse(SBx1, SBy2, IBdiam, IBdiam);
ellipse(SBx1, SBy3, IBdiam, IBdiam);
ellipse(SBx2, SBy2, IBdiam, IBdiam);
ellipse(SBx2, SBy3, IBdiam, IBdiam);
ball3y -= 10;
ball4y += 10;
if(SBy2 > 130 & SBy2 < 170){ //diam increases
IBdiam += 3;
}
}
}
}
//pulsing balls
if(frameCount > 350 & frameCount % 2 == 0){
IBdiam += 16;
}
if(frameCount > 360 & frameCount % 3 == 0){
IBdiam -= 20;
}
}
```