Final Project: An Animated Rant

For my final project I was inspired by the Facebook page Zoom memes for self quarantines. Over the course of the past semester I’ve found posts that I really resonated with. Although it is a meme page – there are a lot of references to mental health and how the current pandemic and other social issues are affecting our lives beyond the Zoom classroom stress. My project uses mainly black and white colors to reflect the seriousness of the issue and to address topics of funny conversations as something bigger than that and in dire need of attention.

Beyond being a student, I also work full-time so life was getting difficult to balance. So I also found aspects of this rant to encompass elements of work from home life as well and that I do understand both sides of the story.

Now to get into how the program works. It is an interactive “flip book” where you can interact with certain pages with your cursor. Simply moving the cursor along the x and y axis of certain pages reveals new elements or changes existing one. Each of the interactions are in place to put emphasis on certain aspects of the text components but some are only animations. If I had more time to flush out some more details – I would have liked to add flame element to the last page. I think that additional interaction would have also made it more engaging.

Please feel free to interact with it below 🙂

sketch

//Helen Cheng
//helenc1@andrew.cmu.edu
//Final Project
//Section C

// text verses
var page1 = ["i'm tired.", "school is hard.", " navigating life", "during a pandemic", "is hard."]
var page2 = ["staring at a screen from ", "morning to night is hard on my eyes.",
"my vision is becoming fuzzy"];
var page3 = ["paying attention during a Zoom lecture is hard.",
"i already couldn't pay attention in person."]
var page4 = ["doing homework is hard.", "i'm not procrastinating",
"i have 3 homeworks,", "an exam,", "and a project,", "all due on the same day",
"i have to choose which one i don't want to", "'procrastinate on this time.'"];
var page5 = ["it feels like", "i'm overwhelmed"];
var page6 = ["you might feel the same way too.", "so let's all just be kind"]
var page7 = ["has anyone stopped to ask us how we feel?"]
var page8 = ["i'm burnt out."];

// global variables
var pageTracker = 0;
var sentenceTracker = 0;

//for text avoidance function
var minMouseDist = 1000;

//var for helper functions
var floater = [];

function setup() {
    createCanvas(500, 500);
    background(0);
    frameRate(1);
    textAlign(LEFT);
    textFont("serif", 20);
    imageMode(CENTER);

    //setup for page 4 - mouse repelling letters
    //characters into array
    points = new Array(page4[1].length);
    for (var i = 0; i < points.length; i++) {
        points[i] = new Array(2);
    }
    var textW = textWidth(page4[1]);
    var s2 = "";
    // logs location of characters
    for (var i = 0; i < page4[1].length; i++){
        var charPosn = textWidth(s2);
        points[i][0] = createVector((width - textW) / 2 + textWidth(s2), height / 2);
        s2 = s2 + page4[1].charAt(i);
        console.log("s2: " + s2);
    }
    console.log(points);

    //setup for floaters
    for (var i = 0; i < 100; i++) {
        floater.push(makeFloaters(random(width), random(height), 
            random(30), color(random(255), 0, 0), random(-5, 5), random(-5, 5)));
    }
}


function draw() {
    background(0);
    fill(255);

    // starting screen with instructions
    if (pageTracker == 0) {
        textSize(42);
        text("new frustrations", 200, 250);
        textSize(20);
        text("an interactive rant: flip through with arrow keys", 50, 400);
        text("interact by moving your mouse", 50, 450);
        text(concat(str(pageTracker), "/8"), 450, 450);
    }

    //auto displays all strings in a simple animation
    else if (pageTracker == 1) {
        background(0);
        textSize(42);
        text(page1[sentenceTracker], 50, 250);
        textSize(20);
        text(concat(str(pageTracker), "/8"), 450, 450);
    
        if (sentenceTracker < 4) {
            sentenceTracker += 1;
        } 
   }
   //red floaters mimic tired eyes
   else if (pageTracker == 2) {
        frameRate(10);
        animation2();
        for (var i = 0; i < 100; i++) {
            floater[i].drawFunction();
            floater[i].moveFunction();
        }
   }
   //flashing letters makes text harder to read and references attention issues
   else if (pageTracker == 3) {
        animation3();
        fill(255);
        text(concat(str(pageTracker), "/8"), 450, 450);
   }
   //red text avoids cursor to represent procrastination
   else if (pageTracker == 4) {
        animation4();
        fill(255);
        text(concat(str(pageTracker), "/8"), 450, 450);
   }
   //mouseY affects text size
   else if (pageTracker ==5) {
        animation5();
        textSize(20);
        text(concat(str(pageTracker), "/8"), 450, 450);
   }
   //mouseX reveals two sides
   else if (pageTracker == 6)  {
        animation6();
        fill(255);
        text(concat(str(pageTracker), "/8"), 450, 450);
   }
   //mouseY turns a smile upside down
   else if (pageTracker == 7) {
        animation7();
        text(concat(str(pageTracker), "/8"), 450, 450);
   }
   //flashing red text simulates emergency or error text above toaster
   else if(pageTracker == 8) {
        animation8();
        textSize(20);
        fill(255);
        text(concat(str(pageTracker), "/8"), 450, 450);
   }

}

// the page turner 
function keyPressed() {
    background(0);
    if (keyCode === LEFT_ARROW) {
        pageTracker -= 1;
    }
    else if (keyCode === RIGHT_ARROW) {
        pageTracker += 1;
    }

}

//page 5 helper functions
function makeFloaters(x, y, s, c, dx, dy) {
    var floater = new Object();
    floater.x = x;
    floater.y = y;
    floater.size = s;
    floater.c = c;
    floater.dx = dx;
    floater.dy = dy;
    floater.drawFunction = drawFloaters;
    floater.moveFunction = moveFloaters;
    return floater;
}

function moveFloaters() {
    this.x += this.dx;
    this.y += this.dy; 
}

function drawFloaters() {
    fill(this.c);
    ellipse(this.x, this.y, this.size);
}

//page 2: random circles float across the screen to mimic tired eyes
function animation2() {
    fill(255);

    textFont("serif", 20);

    text(page2[0], 100, height/4);
    text(page2[1], 200, height/2);
    text(page2[2], 100, 3*height/4);

    text(concat(str(pageTracker), "/9"), 450, 450);
}


//page 3: moving in and out of focus mimics attention disorders
function animation3() {
    strokeWeight(0);

    fill(128 + sin(frameCount*0.2) * 128);

    text(page3[0], 50, height/3);
    text(page3[1], 50, height/2);
}

//page 4: all text displayed at once but is repelled by cursor
//to symbolize avoidance/procrastination
function animation4() {
    background(0);
    text(page4[0], 50, 50);
    for (var i = 2; i < 8; i++){
        if (i < 5) {
            text(page4[i], 50, 50*i);
        }
        else {
            text(page4[i], 50, 400+50*(i - 6));
        }
    }
    //repels text from cursor
    for(var i = 0; i < points.length; i++){
        var p = points[i][0];
        var p2 = createVector(0, 0);
        var mouseDist = dist(p.x, p.y, mouseX, mouseY);
    
        if(mouseDist < minMouseDist){
            p2 = createVector(p.x - mouseX, p.y - mouseY);   
            var distDifference = minMouseDist - mouseDist;
            p2.setMag(sqrt(distDifference));
    }
    points[i][1] = p2;
    //draws text
    fill(255, 0, 0);
    text(page4[1].charAt(i), p.x + p2.x, p.y + p2.y);
    }   
}

//page 5: text grows in size with mouse position
function animation5() {
    text(page5[0], 100, height/3);
    textSize(mouseY/4);
    text(page5[1], 100, height/2);
}

//page 6: text reveals to show the two sides/perspectives
function animation6() {
    fill(255);
    rect(0, 0, mouseX/2, 500);
    rect(500, height, mouseX/2, 500);
    fill(255);
    text(page6[0], 100, height/3);
    fill(0);
    text(page6[1], 100, height/2);
}

//page 7: smiley face turns from smile to frown
function animation7() {
    ellipse(200, 200, 50, 70);
    ellipse(300, 200, 50, 70);
    //smiles at top half, frowns at bottom half of canvas
    noFill();
    strokeWeight(5);
    stroke(255);
    if (mouseY < 250) {
        arc(250, 300, 100, 50+mouseY/5, 0, PI);
    }
    else {
        arc(250, 300, 100, mouseY/5, PI, 2*PI);
    }
    strokeWeight(0);
    fill(255);
    text(page7[0], 80, 100);
}

//page 8: toaster
function animation8() {
    rectMode(CENTER);
    var toaster = 300;
    //toaster side view
    fill(220);
    rect(width/2, height/2, 200, 100);
    ellipse(170, 210, 50, 30);
    ellipse(330, 210, 50, 30);
    rect(width/2, 300, 220, 20);
    rect(350, 230, 20, 10);
    fill(128 + sin(frameCount*0.2) * 128, 0, 0);
    
    textSize(40);
    text(page8[0], 140, 100);
}

Leave a Reply