Project 3: Dynamic Drawing

Contrary to popular belief, fish bowls are too small for the average betta or goldfish and will likely either stunt their growth or kill them due to the lack of space. I thought it would be cool to bring some awareness about this overlooked fact through this project. The fish will either live and emit bubbles or flip over and die depending on the mouse’s position on canvas.

fishbowl
var bgColor;
var bowlColor;
var bodyPurple;
var bodyGray;
var bodyAngle;
var eyeAngle;
var pupilAngle;
var finOrange;
var finGray;
var floatY;

var angle = 0;
var offWeed = 1;
var wiggleWeed = 1;
var bubbles = [];

function setup() {
    createCanvas(600, 450);

    bgColor = color(255, 247, 219);
    bowlGreen = color(110, 245, 234, 120);
    bowlGray = color(190, 212, 209, 200);
    weedGreen = color(78, 186, 159);
    weedGray = color(114, 130, 126);
    sandOrange = color(245, 147, 132);
    sandGray = color(173, 160, 158);
    bodyPurple = color(155, 159, 242);
    bodyGray = color(113, 113, 117);
    finOrange = color(255, 115, 87);
    finGray = color(156, 144, 142);
    bubblesBlue = color(92, 209, 203, 80);
    invisibleColor = color(92, 209, 203, 0);
    castleColor = color(255, 181, 181);
}

function bubble(x,y) {
    let bubblesColor = map(mouseX, 0, width, 0, 1);
    var lerpBubbles = lerpColor(bubblesBlue, invisibleColor, bubblesColor);
    fill(lerpBubbles);
    ellipse(x, y, 15);
  }

function draw() {
    background(bgColor);
    noStroke();

    //seaweed
    let weed = map(mouseX, 0, width, 0, 1);
    var weedColor = lerpColor(weedGreen, weedGray, weed);
    fill(weedColor);

    beginShape();
    vertex(y + 500, x);
    for(var x = 0; x < width; x++){
        var angle = offWeed + x * 0.03;
        var y = map(sin(angle), -wiggleWeed, wiggleWeed, 170, 200);
    vertex(y + 90, x + 100);
  }
    vertex(275, 100);
    endShape();
    offWeed += 0.01;
  
    beginShape();
    vertex(newY + 600, x - 200);
    for(var x = 0; x < width; x++){
        var angle2 = offWeed + x * 0.02;
        var newY = map(sin(angle2), -wiggleWeed, wiggleWeed, 250, 230);
    vertex(newY - 10, x + 160);
  }
    vertex(newY - 5, x);
    endShape();
    offWeed += 0.03;
  
    beginShape();
    vertex(freshY, x);
    for(var x = 0; x < width; x++){
        var angle3 = offWeed + x * 0.04;
        var freshY = map(sin(angle3), -wiggleWeed, wiggleWeed, 175, 160);
    vertex(freshY + 40, x + 140);
  }
    vertex(freshY + 30, x);
    endShape();
    offWeed += 0.01;

    //cover bottom half of seaweed
    fill(bgColor);
    rect(50, 320, 400, 200);

    //castle
    fill(castleColor);
    rect(355, 250, 55, 70);
    rect(355, 240, 10, 10);
    rect(380, 240, 10, 10);
    rect(400, 240, 10, 10);

    //castle window
    fill(161, 93, 93);
    rect(370, 260, 10, 20, 10);

    //rocks
    fill(97, 100, 201);
    ellipse(350, 310, 40, 40);
    fill(247, 104, 185);
    ellipse(230, 310, 40, 30);
    fill(171, 92, 191);
    ellipse(320, 310, 40, 30);
    fill(119, 224, 172);
    ellipse(255, 310, 35, 25);
    fill(247, 104, 185);
    ellipse(390, 310, 25, 25);

    //fishbowl
    let fishbowl = map(mouseX, 0, width, 0, 1);
    var bowlColor = lerpColor(bowlGreen, bowlGray, fishbowl);
    fill(bowlColor);
    ellipse(width/2, height/2, 300, 300);

    //bubbles
    bubble(240, floatY + 20);
    bubble(245, floatY + 10);
    bubble(250, floatY + 40);
        
    if (mouseX <= width/2.2) {
        floatY = floatY - 0.4
    } else {
        floatY = 150;
    }

    //fin colors
    let finColor = map(mouseX, 0, width, 0, 1);
    var fishFins = lerpColor(finOrange, finGray, finColor);
    fill(fishFins);

    push();
    //rectMode(CENTER);
    translate(width/2, height/2);
    let finAngle = atan2(mouseY - height/2, mouseX - width/2);
    rotate(finAngle);
    //bottom fin
    arc(0, -25, 40, 40, PI + HALF_PI, TWO_PI);

    //tail
    arc(-40, 0, 75, 75, HALF_PI + QUARTER_PI, PI + QUARTER_PI);
    pop();

    //top fin
    push();
    translate(width/2, height/2);
    let topfinAngle = atan2(mouseY - height/2, mouseX - width/2);
    rotate(topfinAngle);
    shearX(-35);
    rect(-10, 25, 50, 25, 70, 5, 70, 10);
    pop();

    //fish body
    let bodyColor = map(mouseX, 0, width, 0, 1);
    var fishBody = lerpColor(bodyPurple, bodyGray, bodyColor);
    fill(fishBody);
    push();
    rectMode(CENTER);
    translate(width/2, height/2);
    let bodyAngle = atan2(mouseY - height/2, mouseX - width/2);
    rotate(bodyAngle);
    rect(0, 0, 100, 55, 30);

    //eye
    fill(255);
    ellipse(25, 5, 20, 20);

    //pupil
    var stopMouseX = constrain(mouseX, 0, 600); //constrain mouseX to canvas
    let dilate = map(stopMouseX, 0, width, 10, 18);
    fill(0);
    ellipse(25, 5, dilate, dilate);

    //mouth
    fill(fishBody);
    rect(50, 0, 10, 5, 20);
    rect(50, -5, 10, 5, 20);
    pop();


    //sandy bottom
    push();
    noStroke();
    let sandColor = map(mouseX, 0, width, 0, 1);
    var coarse = lerpColor(sandOrange, sandGray, sandColor);
    fill(coarse);
    arc(300, 310, 225, 120, TWO_PI, PI);
    pop();

    //bubbles floating
    for (let i = 0; i < bubbles.length; i++) {
        bubbles[i].move();
        bubbles[i].show();
        bubbles[i].update();
    }

    //top of the fishbowl
    fill(bgColor);
    rect(50, 0, 400, 120);
}

Leave a Reply