//Steven Fei & Mike Jin
//Section A & C
//Final Project
//zfei@andrew.cmu.edu & fjin@andrew.cmu.edu
var starNumber = 150;//number of the stars on the background
var starsize = 1.5;//size of the stars
var sx = [];//array to define the x position of the stars
var sy = [];//array to define the y position of the stars
var sz = [];//array to define the z position of the stars
var amplitude = 3.14 * 3;//define the moving margin of the stars
var waveSpeed;//define the moving speed of the stars on the background
var theta = 0;//define the moving angle of the stars
var glowDefiner = [];//define the true false value for whether to let the star glow
var glowSize = 22;//glowing size of the stars
var newStars = [];//array for making new stars
var mouseXList = [];//arrays to store mouseX value
var mouseYList = [];//arrays to store mouseY value
var img; //load image for the earth texture mapping
var w = 600 / 7 // devivded the canvas into seven regions and from left to right, the pitches of the piano sound will progressively become higher
var mySndC; //Piano note C
var mySndD; //Piano note D
var mySndE; //Piano note E
var mySndF; //Piano note F
var mySndG; //Piano note G
var mySndA; //Piano note A
var mySndB; //Piano note B
var newExplod = [];//array for making new explosion at the background
var mouseXListEx = [];//arrays to store mouseX value
var mouseYListEx = [];//arrays to store mouseY value
function preload(){
//coded by Mike
//preload the soundtrack of each piano notes to the file
mySndC = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/c-1.wav");
mySndD = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/d-1.wav");
mySndE = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/e-1.wav");
mySndF = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/f-1.wav");
mySndG = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/g-1.wav");
mySndA = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/a-1.wav");
mySndB = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/b-1.wav");
mySndC.setvolume(1);
mySndD.setvolume(1);
mySndE.setvolume(1);
mySndF.setvolume(1);
mySndG.setvolume(1);
mySndA.setvolume(1);
mySndB.setvolume(1);
}
function setup() {
//load the background image for the texture mapping of the earth
//coded by Mike
img = loadImage("https://i.imgur.com/lamlO83.jpg");
createCanvas(600, 600,WEBGL);
//create values for the positions of the stars on the background
//coded by Steven
for (var i = 0; i < starNumber; i++){
sx.push(random(-width * 0.75, width * 0.75));
sy.push(random(-height, height));
sz.push(random(-width, height/2));
var toggle = random(1.0);
//define whether the stars on the background will glow
if(toggle < 0.9){
glowDefiner.push(false);
}else{
glowDefiner.push(true);
}
}
for(var j = 0; j < glowDefiner.length; j++){
print(glowDefiner[j]);
}
}
function draw(){
background(0);
noStroke();
normalMaterial();
centerCube();//create a center star to give a sense of what perspective we are looking at
makeCamera();//use the makeCamera function to change the viewport angle
makeearth();
push();
//draw the stars on the background
for(var i = 0; i < starNumber; i++){
//coded by Steven
push();
waveSpeed = map(sz[i], -width, height/2, 15000, 60000);//define the moving speed of the stars
theta += (TWO_PI / waveSpeed);//define the moving angle of the stars
if(theta > amplitude){
theta = -theta;//set the moving margins of the stars
}
sy[i] += sin(theta);//set the moving value to the positions
sx[i] += cos(theta);//set the moving value to the positions
translate(sx[i], sy[i], sz[i]);
//coded by Mike
if(glowDefiner[i]){
fill(255, 200, 130, 4);
sphere(glowSize);//draw glow light of the sphere
}
fill("white");
smooth();
sphere(starsize);//draw the stars
pop();
}
pop();
push();
//make the planet
if (mouseXListEx.length != 0){
for(var k = 0; k < newExplod.length; k++){
newExplod[k].updateExplo();//animate the expansion of the stars
push();
translate(newExplod[k].x, newExplod[k].y,0);
rotateX(frameCount * 0.05 + k*2);//rotate the new star
rotateY(frameCount * 0.05 + k*2);//rotate the new star
newExplod[k].draw();//animate the emergence of the stars
pop();
}
}
if(newExplod.length > 2){
newExplod.shift();
}
pop();
push();
// make the explosion
if (mouseXList.length != 0){
for(var k = 0; k < newStars.length; k++){
newStars[k].updateStar();//animate the expansion of the explosion in the background
push();
translate(newStars[k].x, newStars[k].y,0);
newStars[k].draw();//animate the emergence of the stars
pop();
}
}
if(newStars.length > 4){
newStars.shift();
}
pop();
}
function makeCamera(){
//coded by Steven
camX = map(mouseX, 0, width, -width/2, width/2);//changing camera position x
camY = map(mouseY, 0, height, -height/2, height/2);//changing camera position y
camZ = height/2;//changing camera position z
camera(camX, camY, camZ,0,0,0,1,1,0);//allow the viewport angle to change
}
//make object to create new stars
function makeNewStar(x, y, radius){
//coded by Steven
var newstar = {x: x,
y: y,
r: radius,
updateStar: updateStar,
draw: drawNewStar};
return newstar;
}
function makeNewExplo(x, y, radius){
//coded by Mike
var newExplo = {x: x,
y: y,
r: radius,
updateExplo: updateExplo,
draw: drawNewExplo};
return newExplo;
}
//function to draw new star
function drawNewStar(){
//coded by Mike
var color1 = random(150, 255);
var color2 = random(100,180);
var color3 = random(100,200);
var density = random(14,20);//allow different numbers of the spheres to appear on the star
for(var i = 0; i < density; i++){
var lengthValue = map(i, 0, density, -PI, PI); //set longitudinal value
for(var j = 0; j< density; j++){
var widthValue = map(j, 0, density, -PI/2, PI/2);// set horizontal value
var pX = this.r * sin(lengthValue) * cos(widthValue);
var pY = this.r * sin(lengthValue) * sin(widthValue);
var pZ = this.r * cos(lengthValue);
push();
fill(color1, color2, color3);
translate(pX, pY, pZ);
sphere(1.6);
pop();
}
}
}
function drawNewExplo(){
//coded by Mike
var color4 = random(100, 255);
var color5 = random(100,180);
var color6 = random(100,200);
var density = random(12, 15);//allow different numbers of the spheres to appear for the explosion
for(var i = 0; i < density; i++){
var lengthValue = map(i, 0, density, -PI, PI); //set longitudinal value
for(var j = 0; j< density; j++){
var widthValue = map(j, 0, density, -PI/2, PI/2);// set horizontal value
var pX1 = this.r * sin(lengthValue) * cos(widthValue * 0.5) * 0.5;
var pY1 = this.r * sin(lengthValue * 0.5) * sin(widthValue) * 0.5;
var pZ1 = this.r * cos(lengthValue);
push();
fill(color4, color5, color6);
translate(pX1, pY1, pZ1);
box(2, 2, 2);
pop();
}
}
}
function updateExplo(){
//coded by Mike
this.r += random(1,2);//allow the new explosion to expand
}
function updateStar(){
//coded by Mike
this.r += random(0.5,2);//allow the new star to expand
}
function mousePressed(){
//coded by Steven
var newStarMaking = [];//empty list for the making new star when mouse is pressed
var newMouseXList = [];
var newMouseYList = [];
var newExploMaking = [];
var newmouseXListEx = [];
var newmouseYListEx = [];
var clickEx;//check whether there is existing new stars
var click;//check whether there is existing new stars
if(mouseXList.length == 0){
click = 0;//count whether the times of starting the object
newStarMaking.push(newStars[0]);//assign values to new arrays to store valid value
newMouseXList.push(mouseXList[0]);//assign values to new arrays to store valid value
newMouseYList.push(mouseYList[0]);//assign value to new arrays to store valid value
}
else{
//define the initiating position according to the mouse position
for(var l = 0; l < newStars.length; l++){
var distance = dist(mouseX - width/3, mouseY - height/3, newStars[l].x, newStars[l].y);
if(distance <= 30){
click = 1;
}else{
click = 0;
newStarMaking.push(newStars[l]);//assign values to the new array
newMouseXList.push(mouseXList[l]);//assign values to the new array
newMouseYList.push(mouseYList[l]);//assign values to the new array
}
}
//get the valid value back to the list
newStars = newStarMaking;
mouseXList = newMouseXList;
mouseYList = newMouseYList;
}
//avoid invalid value
if(click == 0){
mouseXList.push(mouseX - width/3);
mouseYList.push(mouseY - width/3);
var newStar = makeNewStar(mouseX - width/3, mouseY-width/3, 30);
newStars.push(newStar);
}
//add value to empty list
if(mouseXListEx.length == 0){
clickEx = 0;
newExploMaking.push(newExplod[0]);
newmouseXListEx.push(mouseXListEx[0]);
newmouseYListEx.push(mouseYListEx[0]);
}
else{
//assign initiating position according to the mouse postion
for(var w = 0; w < newExplod.length; w++){
var distance = dist(mouseX - width/3, mouseY - height/3, newExplod[w].x, newExplod[w].y);
if(distance <= 30){
clickEx = 1;
}else{
clickEx = 0;
newExploMaking.push(newExplod[w]);
newmouseXListEx.push(mouseXListEx[w]);
newmouseYListEx.push(mouseYListEx[w]);
}
}
//assign values back to the list
newExplod = newExploMaking;
mouseXListEx = newmouseXListEx;
mouseYListEx = newmouseYListEx;
}
//avoid invalid value
if(clickEx == 0){
mouseXListEx.push(mouseX - width/3);
mouseYListEx.push(mouseY - width/3);
var newExplo = makeNewExplo(mouseX - width/3, mouseY-width/3, 300);
newExplod.push(newExplo);
}
//coded by Mike
//load the sound and defines the regions of the sound
if(mouseX > 0 & mouseX < w){
mySndC.play();
}
if(mouseX > w & mouseX < 2 *w){
mySndD.play();
}
if(mouseX > 2 * w & mouseX < 3 * w){
mySndE.play();
}
if(mouseX > 3 * w & mouseX < 4 * w){
mySndF.play();
}
if(mouseX > 4 * w & mouseX < 5 * w){
mySndG.play();
}
if(mouseX > 5 * w & mouseX < 6 * w){
mySndA.play();
}
if(mouseX > 6 * w & mouseX < 7 * w){
mySndB.play();
}
}
//function to make a center planet to have some understanding of the perspective
//coded by Mike
function centerCube(){
//make sure the location of the center planet is always at the center of the canvas
push();
var locX = mouseX - height / 2;
var locY = mouseY - width / 2;
ambientLight(50);
directionalLight(255, 0, 0, 0.25, 0.25, 0);
pointLight(0, 0, 255, locX, locY, 250);
ambientMaterial(100);
strokeWeight(0.5);
stroke(255);
smooth();
sphere(40);
pop();
//first ring surronding the planet
push();
rotateZ(frameCount * 0.01);
rotateX(frameCount * 0.01);
rotateY(frameCount * 0.01);
strokeWeight(0.5);
smooth();
stroke(255);
torus(60, 0.5);
pop();
//second ring surronding the planet
push();
rotateZ((100+ frameCount) * 0.01);
rotateX((100 + frameCount) * 0.01);
rotateY((100+ frameCount) * 0.01);
smooth();
strokeWeight(0.5);
stroke(255);
torus(70, 0.5);
pop();
//third ring surronding the planet
push();
rotateZ((200+ frameCount) * 0.01);
rotateX((200 + frameCount) * 0.01);
rotateY((200+ frameCount) * 0.01);
smooth();
strokeWeight(0.5);
stroke(255);
torus(80, 0.5);
pop();
//fourth ring surronding the planet
push();
rotateZ((300+ frameCount) * 0.01);
rotateX((300 + frameCount) * 0.01);
rotateY((300+ frameCount) * 0.01);
smooth();
strokeWeight(0.5);
stroke(255);
torus(90, 1);
pop();
}
//function to make a earth adjacent to the center planet
//coded by Mike and Steven
function makeearth(){
push();
translate(width / 2, height / 3, -150);
rotateX(frameCount * 0.05);
rotateY(frameCount * 0.05);
texture(img);
sphere(20);
pop();
}
Month: December 2019
Mihika Bansal – Final Project
//Mihika Bansal
//mbansal@andrew.cmu.edu
//Section E
//Project 12
var ripples = [];
var color = [];
var b = 238;
var g = 238;
//color for background
function setup() {
createCanvas(480, 480);
}
function draw() {
background(175, g, b); // randomization of background
if (mouseIsPressed){
//when new ripple is created
var newRip = makeRipple(mouseX, mouseY);
//ripple based on mouse position
ripples.push(newRip);
b = random(200, 250);
g = random(200, 240);
//background color changes based on mouse color
}
for(var i = 0; i < ripples.length; i++){
//for the length of the array draw each of the ripples
var r = ripples[i];
r.display();
//display the ripple
}
if(ripples.length > 35){
// makes it so that when ripples are displayed, they will be removed from array
ripples.shift();
ripples.shift();
ripples.shift();
ripples.shift();//removes 4 ripples
}
}
//making the ripples objects
function makeRipple(rX, rY){
var ripple = { x: rX,
y: rY,
diam: 0,
out: 0,
fade: 0,
colorR: generateRandom(0, 75),
colorG: generateRandom(100, 200),
colorB: generateRandom(50, 200), //color stays in blue range
display: drawRipple};
return ripple;
}
function drawRipple(){ // how to display ripple
for (var i = 0; i < 5; i++){
this.diam = this.out - 25 * i; // makes circle size increase
if(this.diam > 0){
// fading out fill and stroke
this.fade = map(this.diam, 0, 300, 255, 100);
//mapping the fill to part of the canvas, so it fades in a certain time
push();
strokeWeight(1);
//stroke will be background color
stroke(175, g, b, this.fade);
fill(this.colorR, this.colorG, this.colorB, this.fade);
//fill is based on the color of the ripple object
ellipse(this.x, this.y, this.diam);
//multiple ripples made from the ellipse
pop();
}
}
// when more ripples in the array/screen, more waves and speed
if(ripples.length > 25){
this.out += 4; // amount ripple changes
}
else {
this.out += 2; //slower speed of ripples
}
}
function generateRandom(x, y){
var r = floor(random(x, y));
//creates random variable + returns it
return r;
}
For my final project, I created a program that creates and animates ripples based on where your mouse touches. The color of the ripples changes randomly but stays in the blue range. The background color also changes randomly. The ripples fade using the map function, and if there are more ripples on the water, they move together faster.
Chelsea Fan & Katrina Hu – Final Project
/* Chelsea Fan and Katrina Hu
Section 1B and Section 1C
chelseaf@andrew.cmu.edu and kfh@andrew.cmu.edu
Project-15
*/
//important variables
var killCount = 0;
var score = 0;
var yCoord = 0;
var snow = [];
var bear = [];
var c1;
var c2;
function setup() {
createCanvas(600, 480);
frameRate(60);
//initial collection of bears
for (i = 0; i < 1; i++) {
var bearY = -40;
bear[i] = makeBear(bearY);
}
//setting color of background
c1 = color(106, 197, 252);
c2 = color(126, 127, 207);
//initial collection of snows
for (i = 0; i < 60; i++) {
var snowx = random(width);
var snowy = random(0, height);
snow[i] = makeSnow(snowx, snowy);
}
}
function draw() {
setGradient(c1, c2);
///////// BY CHELSEA
//draw Sun
noStroke();
fill(255, 252, 227, 120);
ellipse(80, 250, 85, 85);
fill(255, 246, 179, 140);
ellipse(80, 250, 70, 70);
fill(255, 238, 112, 200);
ellipse(80, 250, 50, 50);
//draw background
drawMountains2();
drawMountains();
//bears
updateBear();
removeBearFromView();
addBear();
drawKill();
//more scenery things
drawWater();
drawIce();
snows();
//end of game
endGame();
}
///////// BY KATRINA
function drawKill() {
//printing score and number of bears killed
fill(255);
textSize(20);
textAlign(RIGHT);
noStroke();
text("Kill Count = " + killCount, width - 70, 50);
text("Score = " + score, width - 70, 75);
}
///////// BY CHELSEA
function endGame() {
//end screen if five bears killed
//and restart game button
if(killCount == 5) {
textSize(50);
fill(255);
textAlign(CENTER);
text("GAME OVER", width/2, height/2-100);
for (var i = 0; i < bear.length; i++) {
bear[i].speed = 0;
}
textSize(25);
fill(255, 150);
noStroke();
rect(width/2 - 80, height/2 - 40, 160, 60);
fill(50);
text("RESTART", width/2, height/2);
}
}
///////// BY KATRINA
function mouseClicked() {
//if restart button clicked, reset game
if(killCount == 5) {
if (mouseX > 220 & mouseX < 380 && mouseY > 200 && mouseY < 260) {
bear = [];
killCount = 0;
score = 0;
for (var i = 0; i < bear.length; i++) {
bear[i].speed = 2;
}
}
}
}
///////// BY KATRINA
function setGradient(c1, c2) {
//gradient color sky background
noFill();
for (var y = 0; y < height; y++) {
var inter = map(y, 0, height, 0, 1);
var c = lerpColor(c1, c2, inter);
stroke(c);
line(0, y, width, y);
}
}
///////// BY CHELSEA
function drawWater() {
//water color and transparency
fill(0, 107, 214, 100);
noStroke();
//water level
rect(0, height - (96 * killCount) - 20, width, height + 30)
}
///////// BY KATRINA
function drawIce() {
fill(245, 68, 59);
rect(mouseX + 8, height - (96 * killCount) - 100, 55, 30); //sign
textSize(10);
textFont('Georgia');
fill(255);
rect(mouseX + 8, height - (96 * killCount) - 100, 8, 75); //pole
text('NORTH', mouseX + 55, height - (96 * killCount) - 90); //words
text('POLE', mouseX + 50, height - (96 * killCount) - 75);
fill(162, 232, 250)
rect(mouseX, height - (96 * killCount) - 15, 100, 4); //ice
fill(255);
rect(mouseX, height - (96 * killCount) - 25, 100, 10); //ice
fill(245, 68, 59);
for(lines = 0; lines < 4; lines++) { //stripes
rect(mouseX + 8, height - (96 * killCount) - lines * 20 - 33, 8, 7);
}
fill(255, 242, 145);
ellipse(mouseX + 12, height - (96 * killCount) - 106, 15, 15) //top of pole
}
///////// BY CHELSEA
function drawSnow() {
noStroke();
fill(255, 255, 255, 170); ///snow color and transparency
push();
translate(this.x2, this.y2); //draw snow at x2, y2
ellipse(10, 10, 5, 5); //snow shape
pop();
}
///////// BY CHELSEA
function makeSnow(xlocation, ylocation) {
//snow object
var makeS = {x2: xlocation,
y2: ylocation,
snowx: random(0, width),
snowy: 0,
speed: random(1, 2),
move: moveSnow,
draw: drawSnow}
return makeS;
}
///////// BY CHELSEA
function moveSnow() {
this.y2 += this.speed; //speed of snow moving
if (this.y2 >= height - (96 * killCount) - 30) { //restart snow on top
this.y2 -= height;
}
}
///////// BY CHELSEA
function snows() {
//move and draw all individual snows
for(i = 0; i < snow.length; i++) {
snow[i].move();
snow[i].draw();
}
}
///////// BY CHELSEA
function drawMountains(){
noStroke();
fill(192, 200, 207); //mountain color
beginShape();
for (i = 0; i < width; i++) {
var mountainSpeed = .0005; //speed of mountains moving
var mountainDetail = 0.009; //smoothness of mountains
var t = (i * mountainDetail) + (millis() * mountainSpeed);
//mountain y coord
var y = map(noise(t), 0, 1.2, height/2, height);
//keep drawing mountain
vertex(i, y);
}
//height constriant of mountains
vertex(width, height);
//restart mountains at left side
vertex(0, height);
endShape();
}
///////// BY CHELSEA
function drawMountains2(){
noStroke();
fill(245); //mountain color
beginShape();
for (i = 0; i < width; i++) {
var mountainSpeed = .0003; //speed of mountains moving
var mountainDetail = 0.007; //smoothness of mountains
var t = (i * mountainDetail) + (millis() * mountainSpeed);
//mountain y coord
var y = map(noise(t), 0, 2, height/2, height);
//keep drawing mountain
vertex(i, y);
}
//height constriant of mountains
vertex(width, height);
//restart mountains at left side
vertex(0, height);
endShape();
}
///////// BY KATRINA
function updateBear() {
//move and draw all individual bears
for (var i = 0; i < bear.length; i++) {
bear[i].move();
bear[i].display();
}
}
///////// BY KATRINA
function removeBearFromView() {
//if bear lands on ice, delete bear
for(var i = 0; i < bear.length; i++) {
if (bear[i].x > mouseX & bear[i].x < mouseX + 100 && (bear[i].y > height - (96 * killCount) - 50 && bear[i].y < height - (96 * killCount) - 40)) {
bear.splice(i, 1);
score += 1;
}
//if bear leaves screen, remove from array
else if (bear[i].y > height + 40) {
bear.splice(i, 1);
killCount += 1;
}
}
}
///////// BY KATRINA
function makeBear(startY) {
//bear object
var myBear = {x: random(30, 570),
y: startY,
speed: 2,
move: bearMove,
display: bearDisplay}
return myBear;
}
///////// BY KATRINA
function bearMove() {
//to move bear
this.y += this.speed;
}
///////// BY KATRINA
function bearDisplay() {
//drawing bear shape
noStroke();
fill(255);
ellipse(this.x, this.y, 43, 60); //body
ellipse(this.x + 14, this.y + 25, 12, 20); //right leg
ellipse(this.x - 14, this.y + 25, 12, 20); //left leg
ellipse(this.x, this.y - 30, 27, 32); //head
ellipse(this.x + 9, this.y - 42, 8, 8); //right ear
ellipse(this.x - 9, this.y - 42, 8, 8); //left ear
fill(240);
ellipse(this.x, this.y, 30, 36); //body
fill(210);
ellipse(this.x + 9, this.y - 42, 5, 5); //right inner ear
ellipse(this.x - 9, this.y - 42, 5, 5); //left inner ear
ellipse(this.x, this.y - 31, 9, 9); //snout
fill(0);
ellipse(this.x + 5, this.y - 37, 4, 4); //right eye
ellipse(this.x - 5, this.y - 37, 4, 4); //left eye
ellipse(this.x, this.y - 32, 6, 3); //nose
fill(255);
ellipse(this.x + 5.5, this.y - 35.5, 2, 2); //right inner eye
ellipse(this.x - 5.5, this.y - 35.5, 2, 2); //left inner eye
stroke(0);
line(this.x, this.y - 32, this.x1, this.y - 29) //line from nose
}
///////// BY KATRINA
function addBear() {
//add new bears to array with small probability
var newBearProb = 0.005;
if(random(0,1) < newBearProb) {
bear.push(makeBear(-40));
}
}
Instructions: Move the ice block with mouse to catch the falling bears. If you miss the bears, they will drown and the water level rises. If you miss 5 bears, the game ends. Press Restart to play again!
This was a fun project to make. Collaborating together was very helpful as we could learn from each other’s mistakes. However, it is difficult to code on two computers. We really enjoyed this experience and hope you enjoy the game!
YouieCho-FinalProject
I created an interactive clock that includes two modes that the user can switch between: normal, and Christmas. Each of the two modes draws a green tree and a snowy Christmas tree. In the beginning, the user wouldn’t know what the wiggly lines are drawing, but as they wait, the tree images begin to appear. The drawing refreshes when they switch between the two modes.
The time is displayed quantitatively as numbers and more visually with bars on the tree trunk, and mouse movement creates variant colors for certain features.
/* Youie Cho
Section E
minyounc@andrew.cmu.edu
Final-Project*/
// Set up turtles to draw paths. Two draw their own paths simultaneously.
var ttl;
var ttl2;
var currIter = 0;
// Sets color for tree, outside area, text, and background
var rTree = 0;
var gTree = 100;
var bTree = 0;
var rOutside = 64;
var gOutside = 147;
var bOutside = 255;
var rText = 255;
var gText = 255;
var bText = 255;
var backgroundCol = 255;
// Ball colors (Christmas mode)
var ballcolors = ["red", "green", "pink", "orange", 'rgb(18, 89, 52)',
'rgb(140, 0, 0)', 'rgb(252, 186, 3)', 'rgb(217, 86, 30)'];
// Coordinates and opacity for drawing star at top (Christmas mode)
var x = [300, 311, 333, 319, 321, 300, 279, 281, 267, 289];
var y = [48, 67, 73, 90, 112, 103, 112, 90, 73, 67];
// Opacity for star (Christmas mode)
var opacity = 0;
function setup() {
createCanvas(600, 600);
background("white");
// Create turtles
ttl = makeTurtle(0, 300);
ttl.setWeight(1);
ttl2 = makeTurtle(600, 300);
ttl2.setWeight(1);
}
function draw() {
time(); // Displays time witn numbers
trunk(); // Trunk displays time with bars
star(); // Star displays in Christmas mode
ttl1Mvt(); // ttl1 settings
ttl2Mvt(); // ttl2 settings
// Turtle movement per frame
currIter ++;
ttl.forward(10);
ttl.right(random(-50, 50));
ttl2.forward(10);
ttl2.left(random(-50, 50));
buttons(); // Buttons used to switch between modes
}
function time() {
// Text box
noStroke();
fill(rTree, gTree, bTree);
rectMode(CENTER);
rect(width / 2, 293, 140, 32);
// Display hours with AM/PM mode, minutes, and seconds
noStroke();
fill(rText, gText, bText);
if (hour() > 12) {
textSize(20);
text(hour() - 12, 245, 300);
textSize(10);
text("PM", 345, 300);
} else {
textSize(20);
text(hour(), 245, 300);
textSize(10);
text("AM", 345, 300);
}
textSize(20);
text(minute(), 280, 300);
text(second(), 315, 300);
}
function trunk() {
rectMode(CORNER);
strokeWeight(0.5);
stroke(128, 70, 13);
fill(backgroundCol, backgroundCol, backgroundCol);
rect(259.5, 370, 81, 120);
fill(128, 70, 13);
// Progression of brown bars display time
var prgH = map(hour(), 0, 23, 0, 120);
rect(259.5, 370, 25, prgH);
var prgM = map(minute(), 0, 59, 0, 120);
rect(287.5, 370, 25, prgM);
var prgS = map(second(), 0, 59, 0, 120);
rect(315.5, 370, 25, prgS);
}
function star() {
var nPoints = x.length;
noStroke();
// Star color changes according to mouseX
var starCol = map(mouseX, 0, width, 130, 220);
fill(255, starCol, 100, opacity);
beginShape();
for (var i = 0; i < nPoints; i++) {
vertex(x[i], y[i]);
}
endShape(CLOSE);
noStroke();
}
function ttl1Mvt() {
// Turtle does not go outside of the canvas
if (ttl.x >= width || ttl.x <= 0 || ttl.y >= height || ttl.y <= 0) {
ttl.penUp();
ttl.goto(300, 300);
ttl.penDown();
}
// Color settings for tree area and outside area
if ((ttl.x > 280 & ttl.x < 320 && ttl.y > 90 && ttl.y < 110) ||
(ttl.x > 260 && ttl.x < 340 && ttl.y > 110 && ttl.y < 150) ||
(ttl.x > 240 && ttl.x < 360 && ttl.y > 150 && ttl.y < 200) ||
(ttl.x > 200 && ttl.x < 400 && ttl.y > 200 && ttl.y < 260) ||
(ttl.x > 150 && ttl.x < 450 && ttl.y > 260 && ttl.y < 370)) {
ttl.setColor(color(rTree, gTree, bTree));
} else {
ttl.setColor(color(rOutside, gOutside, bOutside));
}
}
function ttl2Mvt() {
// Turtle does not go outside of the canvas
if (ttl2.x >= width || ttl2.x <= 0 || ttl2.y >= height || ttl.y <= 0) {
ttl2.penUp();
ttl2.goto(300, 300);
ttl2.penDown();
}
// Color settings for tree area and outside area
if ((ttl2.x > 280 & ttl2.x < 320 && ttl2.y > 90 && ttl2.y < 110) ||
(ttl2.x > 260 && ttl2.x < 340 && ttl2.y > 110 && ttl2.y < 150) ||
(ttl2.x > 240 && ttl2.x < 360 && ttl2.y > 150 && ttl2.y < 200) ||
(ttl2.x > 200 && ttl2.x < 400 && ttl2.y > 200 && ttl2.y < 260) ||
(ttl2.x > 150 && ttl2.x < 450 && ttl2.y > 260 && ttl2.y < 370)) {
ttl2.setColor(color(rTree, gTree, bTree));
} else {
ttl2.setColor(color(rOutside, gOutside, bOutside));
}
}
function buttons() {
noStroke();
fill(mouseY / 5 + 200, mouseX / 5 + 200, mouseX / 5 + 100);
rect(13, 558, 100, 33);
rect(487, 558, 100, 33);
strokeWeight(0.5);
fill(rOutside, gOutside, bOutside);
textSize(15);
text("Normal", 40, 580);
text("Christmas", 505, 580);
}
function mousePressed() {
// NORMAL MODE ////////////////////////////////////////////////////////////
if (mouseX >= 13 & mouseX <= 113 && mouseY >= 558 && mouseY <= 691) {
// Turtle drawing refreshes upon cliking the button
noStroke();
clear();
backgroundCol = 255;
background(backgroundCol, backgroundCol, backgroundCol);
opacity = 0;
// Color settings
rTree = 0; // Green tree
gTree = 100;
bTree = 0;
rOutside = 64; // Blue outside
gOutside = 147;
bOutside = 255;
rText = 240; // Light green text
gText = 247;
bText = 218;
}
// CHRISTMAS MODE /////////////////////////////////////////////////////////
if (mouseX >= 487 & mouseX <= 587 && mouseY >= 558 && mouseY <= 691) {
// Turtle drawing refreshes upon cliking the button
clear();
backgroundCol = 0;
background(backgroundCol, backgroundCol, backgroundCol);
opacity = 100; // Displays star only in Christmas mode
// Color settings
rTree = 255; // White tree
gTree = 255;
bTree = 255;
rOutside = 255; // Yellow outside
gOutside = 213;
bOutside = 28;
rText = 248; // Dark yellow text
gText = 178;
bText = 41;
// Ornaments (Christmas mode)
noStroke();
for (var i = 0; i < ballcolors.length; i++) {
for (var j = 0; j < ballcolors.length; j++) {
fill(ballcolors[i]);
}
ellipse(random(280, 320), random(150, 250), 12, 12);
ellipse(random(170, 450), random(250, 370), 18, 18);
}
}
}
// TURTLE FUNCTIONS ///////////////////////////////////////////////////////////
function turtleLeft(d) {
this.angle -= d;
}
function turtleRight(d) {
this.angle += d;
}
function turtleForward(p) {
var rad = radians(this.angle);
var newx = this.x + cos(rad) * p;
var newy = this.y + sin(rad) * p;
this.goto(newx, newy);
}
function turtlePenDown() {
this.penIsDown = true;
}
function turtlePenUp() {
this.penIsDown = false;
}
function turtleGoTo(x, y) {
if (this.penIsDown) {
stroke(this.color);
strokeWeight(this.weight);
line(this.x, this.y, x, y);
}
this.x = x;
this.y = y;
}
function turtleSetColor(c) {
this.color = c;
}
function turtleSetWeight(w) {
this.weight = w;
}
function makeTurtle(tx, ty) {
var turtle = {x: tx, y: ty,
angle: 0.0,
penIsDown: true,
color: color(128),
weight: 1,
left: turtleLeft, right: turtleRight,
forward: turtleForward,
penDown: turtlePenDown, penUp: turtlePenUp,
goto: turtleGoTo,
setColor: turtleSetColor, setWeight: turtleSetWeight,
};
return turtle;
}
Sammie Kim – Final Project – 12
For this project, I wanted to create a recycling game that educates all age levels upon proper recycling, which is one of the basic ways that we can all contribute to protect our environment. Through the process, I learned a lot, especially how there are a lot of trash items that are not recyclable—this emphasized the importance of reusing items and reducing waste in general. The user can simply explore the environment, drag any waste item and drop it in any of the waste bins below. If the waste is thrown in the wrong bin, information will automatically show up on the top to guide the user, while also giving extra tips for reducing such trash.
//Sammie Kim
//Section D
//sammiek@andrew.cmu.edu
//Final Project
//Global Variables
var FOOD = 0; //Index number within the waste bin type array
var PLASTIC = 1;
var PAPER = 2;
var TRASH = 3;
var score = 0;
var styrofoamBox = createStyrofoamBox();
var tissue = createTissue();
var hanger = createHanger();
var newspaper = createNewspaper();
var pizzaBox = createPizzaBox();
var plasticBag = createPlasticBag();
var plasticBottle = createPlasticBottle();
var paperBag = createPaperBag();
var appleCore = createApple();
var coffeeCup = createCoffee();
var fishbones = createFishbones();
var toothpaste = createToothpaste();
var mirror = createMirror();
var bubblewrap = createBubbleWrap();
var foodBin = createFoodBin();
var plasticBin = createPlasticBin();
var paperBin = createPaperBin();
var trashBin = createTrashBin();
var wastes = [styrofoamBox, tissue, hanger, newspaper, pizzaBox, plasticBag,
plasticBottle, paperBag, appleCore, coffeeCup, fishbones,
toothpaste, mirror, bubblewrap];
var wasteBins = [foodBin, plasticBin, paperBin, trashBin];
//Boolean Variables
var correct = false;
var selected = false;
//Use objects to create different wastes and wastebins with specific traits
function createStyrofoamBox() {
var styrofoamBox = {
url: "https://i.imgur.com/Lb1P88W.png",
initX: 78,
initY: 102,
x: 78,
y: 102,
selected: false,
stay: true,
dragging: false,
informing: false,
type: TRASH,
note: "Styrofoam is a non-recyclable material because it contains "
+ "polysteryene, which is non-biodegradable."
}
return styrofoamBox;
}
function createTissue() {
var tissue = {
url: "https://i.imgur.com/s6rZAJu.png",
initX: 145,
initY: 95,
x: 145,
y: 95,
selected: false,
stay: true,
dragging: false,
informing: false,
type: TRASH,
note: "Dirty tissues should be thrown in trash."
}
return tissue;
}
function createHanger() {
var hanger = {
url: "https://i.imgur.com/dE1sDsn.png",
initX: 253,
initY: 163,
x: 253,
y: 163,
selected: false,
stay: true,
dragging: false,
informing: false,
type: TRASH,
note: "Plastic hangers are not purely plastic, and their curved ends "
+ "can be problematic in recycling equipment. "
}
return hanger;
}
function createNewspaper() {
var newspaper = {
url: "https://i.imgur.com/FkD5sJK.png",
initX: 0,
initY: 253,
x: 0,
y: 253,
selected: false,
stay: true,
dragging: false,
informing: false,
type: PAPER,
note: "Newspapers should be recycled in paperbin."
}
return newspaper;
}
function createPizzaBox() {
var pizzaBox = {
url: "https://i.imgur.com/ZRjCbEW.png",
initX: 172,
initY: 102,
x: 172,
y: 102,
selected: false,
stay: true,
dragging: false,
informing: false,
type: TRASH,
note: "Pizzabox cannot be recycled due to its wet and greasy cardboard "
+ "that cannot be processed in recycling equipment. "
+ "It can also attract insects and rodents."
}
return pizzaBox;
}
function createPlasticBag() {
var platicBag = {
url: "https://i.imgur.com/PDtsB6D.png",
initX: 94,
initY: 172,
x: 94,
y: 172,
selected: false,
stay: true,
dragging: false,
informing: false,
type: PLASTIC,
note: "Most recycling facilities can only handle rigid materials that can "
+ "be separated, so plastic bags and wraps are generally not accepted. "
+ "But we can always reuse them for collecting trash."
}
return platicBag;
}
function createPlasticBottle() {
var plasticBottle = {
url: "https://i.imgur.com/6OEa9bA.png",
initX: 393,
initY: 95,
x: 393,
y: 95,
selected: false,
stay: true,
dragging: false,
informing: false,
type: PLASTIC,
note: "Empty plastic bottles belong in the plastic bin. "
+ "The better option is to carry reusable waterbottles."
}
return plasticBottle;
}
function createPaperBag() {
var paperBag = {
url: "https://i.imgur.com/QsPO9ph.png",
initX: 364,
initY: 153,
x: 364,
y: 153,
selected: false,
stay: true,
dragging: false,
informing: false,
type: PAPER,
note: "Clean paper bags belong in the paper bin. Still, the best "
+ "option would be to reuse them."
}
return paperBag;
}
function createApple() {
var appleCore = {
url: "https://i.imgur.com/QX98sKU.png",
initX: 274,
initY: 258,
x: 274,
y: 258,
selected: false,
stay: true,
dragging: false,
informing: false,
type: FOOD,
note: "Any type of leftover food belong in the organic waste bin."
}
return appleCore;
}
function createCoffee() {
var coffeeCup = {
url: "https://i.imgur.com/sys0QnS.png",
initX: 351,
initY: 87,
x: 351,
y: 87,
selected: false,
stay: true,
dragging: false,
informing: false,
type: TRASH,
note: "Unlike most paper items, paper cups are usually coated in platic "
+ "to hold liquid to prevent leaking. "
+ "Although many cafes are beginning to use compostable cups, "
+ "the best option is carrying coffee mugs or reusable bottles."
}
return coffeeCup;
}
function createFishbones() {
var fishbones = {
url: "https://i.imgur.com/wju8gLe.png",
initX: 205,
initY: 264,
x: 205,
y: 264,
selected: false,
stay: true,
dragging: false,
informing: false,
type: FOOD,
note: "Any type of leftover food belong in the organic waste bin."
}
return fishbones;
}
function createToothpaste() {
var toothpaste = {
url: "https://i.imgur.com/na3BnTw.png",
initX: 104,
initY: 260,
x: 104,
y: 260,
selected: false,
stay: true,
dragging: false,
informing: false,
type: PLASTIC,
note: "Toothpaste tubes should be properly cleaned out before "
+ "being placed in the plastic recycling bin."
}
return toothpaste;
}
function createMirror() {
var mirror = {
url: "https://i.imgur.com/NAh1S2x.png",
initX: 142,
initY: 130,
x: 142,
y: 130,
selected: false,
stay: true,
dragging: false,
informing: false,
type: TRASH,
note: "Mirrors cannot be recycled due to the coating used on glass "
+ "to make it reflective. Be sure to wrap broken mirror pieces "
+ "before throwing them in the garbage."
}
return mirror;
}
function createBubbleWrap() {
var bubblewrap = {
url: "https://i.imgur.com/cvJ1Iou.png",
initX: 336,
initY: 245,
x: 336,
y: 245,
selected: false,
stay: true,
dragging: false,
informing: false,
type: TRASH,
note: "Although many plastics are recylable, bubble wraps and bags "
+ "cannot be recyled due to their thin films that can get tangled "
+ "in recycling machines."
}
return bubblewrap;
}
function createPaperBin() {
var paperBin = {
url: "https://i.imgur.com/AgJIG61.png",
x: 229,
y: 342,
}
return paperBin;
}
function createPlasticBin() {
var plasticBin = {
url: "https://i.imgur.com/6x6FPJW.png",
x: 117,
y: 342,
}
return plasticBin;
}
function createFoodBin() {
var foodBin = {
url: "https://i.imgur.com/sSve89v.png",
x: 8,
y: 342,
}
return foodBin;
}
function createTrashBin() {
var trashBin = {
url: "https://i.imgur.com/jm4NMB8.png",
x: 343,
y: 342,
}
return trashBin;
}
function setup() {
createCanvas(450, 480);
}
function draw() {
//load images for background, wastes, and waste bins
background(220);
image(backgroundPic, 0, 0);
for (var i = 0; i < wasteBins.length; i++) {
image(wasteBinsPics[i], wasteBins[i].x, wasteBins[i].y);
}
//Show explanation on top of the canvas if informing is true
for (var i = 0; i < wastes.length; i++) {
if (wastes[i].informing) {
fill(220);
noStroke();
rect(0, 0, 450, 60);
fill(0);
text(wastes[i].note, 10, 10, 440, 480);//wrapping text within canvas
}
if (wastes[i].stay) { //if stay is true, images are all shown on canvas
image(wastePics[i], wastes[i].x, wastes[i].y);
if (wastes[i].dragging) {
//update waste with current mouse locations
wastes[i].x = mouseX - wastePics[i].width / 2;//offset amount
wastes[i].y = mouseY - wastePics[i].height / 2;
}
}
}
if (correct) {
text("Correct!", 10, 20); //shows up when answer is correct
}
fill(255);
text("Score: " + score, 10, 90); //show scoreboard
}
function preload() {
//Preload all the images by pushing the objects' URL into new array
var backgroundURL = "https://i.imgur.com/4jWCbcI.png"
backgroundPic = loadImage(backgroundURL);
wastePics = [];
for (var i = 0; i < wastes.length; i++) {
wastePics.push(loadImage(wastes[i].url));
}
wasteBinsPics = []
for (var i = 0; i < wasteBins.length; i++) {
wasteBinsPics.push(loadImage(wasteBins[i].url));
}
}
function mousePressed() {
//Use mousePressed to drag each trash item within the canvas
//I created parameters for each trash image, so that the mouse can click
//within the area of each trash image.
for (var i = 0; i < wastes.length; i++) {
wastes[i].informing = false; //Clear information when mouse is pressed.
var x0 = wastes[i].x; //top left X coordinate
var y0 = wastes[i].y; //top right Y coordinate
var x1 = wastes[i].x + wastePics[i].width; //top right X coordinate
var y1 = wastes[i].y + wastePics[i].height; //bottom y coordinate
if (!selected & x0 < mouseX && mouseX < x1 && y0 < mouseY && mouseY < y1) {
selected = true; //trash is selected within the image boundaries
wastes[i].dragging = true;
}
}
}
function mouseReleased() {
//Use mouseReleased to evaluate whether the chosen trash is
//dropped into the correct bin.
//Like previously, I created specific parameters for trashbin images.
selected = false;
for (var i = 0; i < wastes.length; i++) {
if (wastes[i].dragging) {
wastes[i].dragging = false;
var corrBin = wasteBins[wastes[i].type];
var corrBinPic = wasteBinsPics[wastes[i].type];
var x0 = corrBin.x;
var y0 = corrBin.y;
var x1 = corrBin.x + corrBinPic.width;
var y1 = corrBin.y + corrBinPic.height;
if (y0 < mouseY & mouseY < y1) {
//Since all trashbins have the same Y height, I differentiated
//the correct bin by determining the X locations
if (x0 < mouseX && mouseX < x1) { //Correct Bin
correct = true;
wastes[i].stay = false; //waste will disappear
wastes[i].informing = false; //information will not show
score += 1; //score is updated by one when answer is correct
} else {
//if incorrect, information will show up, and
//the waste image will go back to its initial location
correct = false;
wastes[i].informing = true;
wastes[i].x = wastes[i].initX; //initial X coordinate
wastes[i].y = wastes[i].initY; //initial Y coordinate
}
} else {
correct = false; //the default status
}
}
}
}
Joseph Zhang – Final Project -12
// Joseph Zhang
// 15-104 Final Project
// Section E
var rectangles = [];
var gutter = 30;
var totalRows = 15;
var totalCols = 15;
var centerCol = totalCols / 2;
var centerRow = totalRows / 2;
var rectH = 70;
function setup() {
createCanvas(450, 450, WEBGL);
// PUT RECTANGLES INTO ARRAY
for( x = 0; x < totalRows; x++) {
for ( y = 0; y < totalCols; y++) {
rectangles.push(createCube(x * gutter, y * gutter, x, y));
}
}
}
var bgColor;
var bg = 0;
function draw() {
rotateY(map(mouseX, 0, height, -.15, .15));
rotateX(map(mouseY, 0, height, .15, -.15));
translate(map(mouseX / 10 , 0, width / 10, -10, 10), map(mouseY / 10 , 0, height / 10, -10, 10), 0);
//INTERACTIVE CONTROLS - UP AND DOWN
if( keyIsPressed & keyCode === LEFT_ARROW) {
if( rectH > -200) {
rectH -= 3;
print(rectH);
}
}
else if( keyIsPressed & keyCode === RIGHT_ARROW) {
if( rectH < 100) {
rectH += 3;
print(rectH);
}
}
// COLOR BACKGROUND
if(bgColor) {
if ( bg > 0) {
bg -= 20;
}
}
else{
if( bg < 255) {
bg += 20;
}
}
background(bg);
rectMode(CENTER);
rotateX(radians(40));
translate( - width / 2, - height / 2 + 15, 0);
// REPEATEDLY DRAW EVERY PRISM IN DRAW
for( i = 0; i < rectangles.length; i++) {
rectangles[i].drawRect();
rectangles[i].raiseRect();
}
}
// CUBE OBJECT
function createCube(row, col, r, c) {
var rectObj = {
w: 19,
xPos: row,
yPos: col,
offset: dist(r, c, centerCol, centerRow),
currentHeight: this.offset,
// UPDATES THE HEIGHT OF RECTANGLE
drawRect: function() {
if (this.currentHeight > 0) {
fill(map(this.currentHeight, 10, 70, 0, 255));
}
else{
fill(map(this.currentHeight, 10, 70, 0, -255));
}
push();
translate(this.xPos, this.yPos , this.currentHeight);
box(this.w, this.w, this.currentHeight);
pop();
},
// CHANGES THE HEIGHT THROUGH MAPPING CANVAS
raiseRect: function() {
this.currentHeight = map( sin(this.offset), -1, 1, 10, rectH);
this.offset += .1;
}
}
return rectObj;
}
// IF ENTER KEY IS PRESSED, CHANGE BACKGROUND
function keyPressed() {
if( keyCode === ENTER) {
bgColor = !bgColor;
}
}
INTERACTIVE CONTROLS (click on canvas first):
LEFT ARROW: Decrease wave amplitude
RIGHT ARROW: Decrease wave amplitude
ENTER: Change background color
***IF LAGGING, VISIT https://editor.p5js.org/jxsephz/sketches/9Dqxil-1P
————————
For this project, I wanted to experiment with manipulating forms in three dimensional space. As someone who loves mathematical patterns, I explored ways that I could utilize the oscillation of a Sine wave.
Jamie Park – Final Project
My project was inspired by single-line drawings and line-drawing tools, like etch a sketch. I always had a desire to draw something only using one line, but I did not have the talent to do so. I also never had the patience to draw using etch a sketch. Therefore, I created a p5js drawing tool that allows you to create single-line drawings. In order to draw, use the arrow keys. You can change the color of the line by pressing on the space bar (the circle on the bottom will indicate the current color status), change the line weight by clicking on the arrows (numbers indicate the line weight), and clear canvas by clicking on the “clear” button. I hope you have fun as much as I had while I was coding for this project!
Plus, try drawing a diagonal line by pressing onto two arrow keys at the same time! 🙂
/* Jamie Park (jiminp) Section E
15 - 104 Final Project */
var ttl; //global variable for the turtle
var colors = ["Coral", "DarkTurquoise", "DarkGrey", "blue",
"FireBrick", "Gold", "Lavender", "LightPink", "PowderBlue"]; //global variable for color values
var col = 0; //color index value
var strokeThickness = 2; //strokethickness as global value
var bgCol = 255;
function preload(){
//preload image into the canvas
var overlayURL = "https://i.imgur.com/5dpuHCX.png";
overlay = loadImage(overlayURL);
}
function setup(){
//creates a canvas
createCanvas(500, 400);
//sets the background color on white
background(250);
//makes the turtle at random parts of the canvas
ttl = makeTurtle(random(150, 300), random(100, 300));
ttl.setWeight(strokeThickness);
ttl.setColor("coral");
}
function draw(){
//display the image on the canvas
image(overlay, 0, 0, 500, 400);
//allows the user to draw the lines
drawLines();
//allows the user to change the color of lines
displayStrokeWeight();
drawTriangleButtons();
displayCurrentColor();
clearButton();
boundTurtle();
}
function mousePressed(){
//redraw when clicked on clear button
clearCanvas();
//when tou click the buttons, the thickness of the turtle stroke changes
changeThickness();
}
function boundTurtle(){
//set up local variables that wound bound the turtles
var boundaries = 28;
var bottomBoundaries = 58;
//if turtle x is smaller than a set number, the turtle is the set number
//set number due to the frame around the canvas
if(ttl.x < boundaries){
ttl.x = boundaries;
}
//if turtle y is smaller than a set number...
if(ttl.y < boundaries + 2){
ttl.y = boundaries + 2;
}
//if turtle x is greater than the set number...
if(ttl.x > width - boundaries - 5){
ttl.x = width - boundaries - 5;
}
//if turtle y is greater than the set number...
if(ttl.y > height - bottomBoundaries){
ttl.y = height - bottomBoundaries;
}
}
function keyPressed(){
//when spacebar is pressed, the color of the turtle changes
//you can "find" your desired color by pressing on the space bar multiple times
changeColor();
}
function changeColor(){
if(keyCode === 32){
//keyCode 32 is the space bar
col = (col + 1) % colors.length;
//you change the color by adding one into the color index above
ttl.setColor(colors[col]);
}
}
function drawLines(){
//function that draws the lines when key is pressed accordingly
//local variable that goes forward by 1.5 pixels every time key is pressed
var distDraw = 1.5;
//draws the line leftwards
if(keyIsDown(LEFT_ARROW)){
ttl.face(180);
ttl.forward(distDraw);
}
//draws the line rightwards
if(keyIsDown(RIGHT_ARROW)){
ttl.face(0);
ttl.forward(distDraw);
}
//draws an upward line
if(keyIsDown(UP_ARROW)){
ttl.face(270);
ttl.forward(distDraw);
}
//draws a downward line
if(keyIsDown(DOWN_ARROW)){
ttl.face(90);
ttl.forward(distDraw);
}
}
function changeThickness(){
//thickness of the stroke increases / decreases when the button is clicked
if(mouseX < 450 & mouseX > 430 && mouseY > 280 && mouseY < 300){
strokeThickness = strokeThickness + 1;
//strokeweight increases by 1
}
//when mouseisPressed within the range of the triangular buttons, reduce the stroke weight by 0.05
if(mouseX < 450 & mouseX > 430 && mouseY > 310 && mouseY < 340){
strokeThickness = strokeThickness - 1;
//strokeweight decreases by 1
}
//constrains the thickness of the stroke in value between 1 and 13
strokeThickness = constrain(strokeThickness, 1, 13);
//implements the weight to the turtle
ttl.setWeight(strokeThickness);
}
function drawTriangleButtons(){
//draws the triangle buttons on the bottm right corner of the canvas
noStroke();
fill("LightSalmon");
//local variables that set height and width of the triangle to avoid magic nunbers
var triangleW = 430;
var triangleH = 300;
//top triangle that increases the thickness
triangle(triangleW, triangleH, triangleW + 20, triangleH, triangleW + 10, triangleH - 20);
//bottom triangle to reduce the thickness
triangle(triangleW, triangleH + 10, triangleW + 20, triangleH + 10, triangleW + 10, triangleH + 30);
}
function clearButton(){
//draws the "clear" button on the top left corner
fill("orange");
noStroke();
ellipse(50, 50, 25, 25);
fill("white");
text("clear", 40, 53);
//informative text
fill("gray");
text("press on arrow keys to draw & space bar to change color,", 73, 50);
text("and click on the arrow to change stroke thickness", 73, 60);
}
function clearCanvas(){
//if mouse is within the proximity of the clear button, the canvas is cleared
if(mouseX > 37.5 & mouseX < 62.5 && mouseY > 37.5 && mouseY < 62.5){
clear();
background(255);
//strokeThickness and color index restart
strokeThickness = 2;
col = 8;
}
}
function displayCurrentColor(){
//displays current turtle color in a circle
fill(colors[col]);
ellipse(width * .815, height * .8, 10, 10)
}
function displayStrokeWeight(){
//displays the strokeweight
noStroke();
fill("white");
rect(430, 300, 18, 10);
textSize(10);
fill("SlateGray")
textFont("GillSans");
text(strokeThickness, 435, 308.5);
}
//------------------------------turtle code--------------------------------
function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}
Emma N-M — Final Project
My project is a spirograph application. You can move the two radius sliders, and vary the line length to change the design the math equation will create (the radii must be different values for the DRAW button to work). There are three different math equations you can use to create different designs (spirograph, epitrochoid, or another cool equation). The square in the top right hand corner allows you to set the pen color when you click on the box. This will open up a color gradient. Click anywhere and the box in the bottom righthand will show you a preview of the color you clicked on. Once you are happy with your pen color, hit “ENTER”. This will take you back to the set up screen. Hit the DRAW button to watch your design be created. When watching your drawing, you may hit the back arrow button or press “LEFT ARROW” key to go back to the set up screen. That’s it! Enjoy being mesmerized by art created with math.
/* Emma Nicklas-Morris
enicklas
Section B
Final Project
*/
// radius1 46, radius2 31, LL 30 -- cool design
// point to draw the lines for the design
var x1;
var y1;
var x2 = x1;
var y2 = y1;
// used in sprigraph equations
var scaleN = 2.8;
var i = 0; // counter
var r1 = 10;
var r2 = 11;
var p = 2; // length of line from center
// used in other cool math equation
var l = p / r1;
var k = r1 / r2;
// epitrochoid equation variables
var a;
var b;
// drawing button
var drawing = false;
var justClicked = false;
// back button
var backB = 30;
var backBX = 21;
var buttons = [];
var buttonText = [];
var equationText = [];
var equationCount = 1; // counts times the equation button is clicked
var e; // index to get the right equation displayed
var r1x = 25; // x position of radius 1 slider
var ry = 50; // y position for slider
var r2x = 175; // x position of radius 2 slider
var r1Min = 25; // min x position for radius 1
var r1Max = 125; // max x position for radius 1
var r2Min = 175; // min x position for radius 2
var r2Max = 275; // max x position for radius 2
var radMin = 10; // user min for radii
var rad2Max = 70; // user radius 2 max
var rad1Max = 100; // user radius 1 max
var llMin = 2; // user line length min
var llMax = 65; // user line length max
var px = 315; // x position of line length (p)
var pMin = 315; // min x position of line length (p)
var pMax = 415; // max x position of line length (p)
var dragging = false;
var sliderCol = 170;
// which radius slider is clicked
var rad1 = false;
var rad2 = false;
var lineL = false;
var rd = 12; // ball slider diameter
var r1Num = 10; // radius1 number displayed to user
var r2Num = 10; // radius2 number displayed to user
var lineNum = 5; // line length number displayed to user
var r12; // radius1 - radius2
var diffRadii = false; // can't have the same radii
var backCol = 240; // background color
var userCol = 100; // intializes pen color
var gradSection = 84; // max width of each gradient section
var choosing = false;
var radius2; // object text for radius 2
var lineLen; // object text for line length
// location for elements on the screen
var diffRadX = 150;
var diffRadY = 100;
var eqX = 20;
var eqY = 30;
var rad2X = 190;
var llX = 320;
var colorX = 445;
var colorY = 25;
var colorMid = 165;
var colorPink = 147;
var eqW = 120;
function setup() {
createCanvas(500, 400);
background(backCol);
frameRate(40);
}
function draw() {
// stroke(cos(i/10)*(255/2), 0, sin(i/20)*(255/2), i);
// screen mode: draws the spirograph
if ((drawing) & (diffRadii)) {
// back button on draw screen
drawBackButton();
// hide all setting buttons when in draw mode
if (justClicked) {
fill(backCol);
rect(0, 0, width, height);
justClicked = false;
}
x1 = width / 2;
y1 = height / 2;
// spirograph
if (e === 0) {
spirograph();
}
// Epitrochoid
else if (e === 1) {
epitrochoid();
}
// other cool math equation
else if (e === 2) {
other();
}
}
// screen mode: set the settings
else {
noStroke();
// new screen -- hides drawing
fill(backCol);
rect(0, 0, width, height);
// draws the buttons
makeAndDrawButtons();
makeTextForButtons();
drawText();
displayEquation();
// which slider user is dragging
checkDragging();
// draw choose color button
chooseColor();
// draw radius sliders
radiusSliders();
// draws the example circles for the math
exampleCircles();
// line length (p)
drawLineLength();
// can't draw using the same radii
checkRadii();
// choosing pen color
choosePenColor();
// reset equation variables
x1 = width / 2;
y1 = height / 2;
x2 = undefined;
y2 = undefined;
i = 0;
}
i += 0.1;
}
function checkDragging() {
if (dragging) {
if (rad1) {
r1x = mouseX;
}
else if (rad2) {
r2x = mouseX;
}
else if (lineL) {
px = mouseX;
}
}
}
function drawLineLength() {
if (e === 0) { // spirograph color pallete
stroke("#65cdca");
}
else if (e === 1) { // epitrochoid color pallete
stroke("#c26571");
}
else if (e === 2) { // other cool equation color pallete
stroke("#a0e3b9")
}
line(width/2 + r12, height/2, width/2 + r12 - lineNum, height/2);
ellipse(width/2 + r12, height/2, 2, 2);
ellipse(width/2 + r12 - lineNum, height/2, 3, 3);
}
function exampleCircles() {
strokeWeight(2);
noFill();
// radius 1 circle
stroke(0);
ellipse(width/2, height/2, 2*r1Num, 2*r1Num);
// radius 2 circle
if (e === 0) { // spirograph
stroke("#3f807e");
}
else if (e === 1) { // epitrochoid
stroke("#82444c");
}
else if (e === 2) { // other cool equation
stroke("#3d5747")
}
if ((e === 0) || (e === 2)) { // spirograph -- circles inside
r12 = r1Num - r2Num;
}
else { // epitrochoid -- cirlces outside
r12 = r1Num + r2Num;
}
ellipse(width/2 + r12, height/2, 2*r2Num, 2*r2Num);
}
function choosePenColor() {
if (choosing) {
noStroke();
fill(255);
rect(0 ,0, width, height);
// the six color gradients
gradient();
// color box to see which color is clicked
stroke(0);
strokeWeight(2);
fill(userCol);
rect(445, 350, 30, 30);
}
}
function checkRadii() {
if (diffRadii == false) {
noStroke();
if (e === 0) { // spirograph
fill("#65cdca");
}
else if (e === 1) { // epitrochoid
fill("#c26571");
}
else if (e === 2) { // other cool equation
fill("#a0e3b9");
}
textSize(18);
text("Please choose two different radii", diffRadX, diffRadY);
}
}
function spirograph() {
// update spirograph variables according to user input
r1 = r1Num;
r2 = r2Num;
p = lineNum;
k = r2 / r1;
x1 += scaleN*(r1 - r2)*cos(k*i) + p * cos((1-k)*i);
y1 += scaleN*(r1-r2)*sin(k*i) - p * sin((1-k)*i);
strokeWeight(2);
stroke(userCol);
// draw small portion of design
line(x2, y2, x1, y1);
noStroke();
x2 = x1;
y2 = y1;
}
function epitrochoid() {
r1 = r1Num;
r2 = r2Num;
p = lineNum;
a = r1 + r2;
b = a / r2;
scaleN = .9;
x1 += scaleN*a*cos(i) - p * cos(b*i);
y1 += scaleN*a*sin(i) + p * sin(b*i);
stroke(userCol);
strokeWeight(2);
line(x2, y2, x1, y1); // draw small portion of design
noStroke();
x2 = x1;
y2 = y1;
}
function other() {
// update spirograph variables according to user input
r1 = r1Num;
r2 = r2Num;
p = lineNum;
l = p / r1;
k = r2 / r1;
scaleN = 2;
x1 += scaleN*r1*((1-k)*Math.cos(i) + l*k*cos(i*((1-k)/k)));
y1 += scaleN*r1*((1-k)*Math.sin(i) + l*k*sin(i*((1-k)/k)));
stroke(userCol);
strokeWeight(2);
line(x2, y2, x1, y1); // draw small portion of design
noStroke();
x2 = x1;
y2 = y1;
}
function makeAndDrawButtons() {
// make the buttons
var drawButton = makeButton(7/9 * width, 6/7 * height, 4 * eqX, eqY, "rect");
drawButton.color(0);
buttons.push(drawButton);
var equationB = makeButton(eqX, 7/8 * height, diffRadX, eqY - 5, "rect");
equationB.color(0);
buttons.push(equationB);
// draw all the buttons
for (var b = 0; b < buttons.length; b++) {
buttons[b].draw();
}
}
function makeTextForButtons() {
// make text for buttons
var textOnButton = makeText("DRAW", 7/9 * width + 9, height - eqY - 5, eqX);
textOnButton.color(240);
buttonText.push(textOnButton);
var spiro = makeText("SPIROGRAPH", eqX * 2, height - eqY - 1, 16);
spiro.color("#65cdca");
equationText.push(spiro);
var epi = makeText("EPITROCHOID", eqX * 2, height - eqY - 1, 16);
epi.color("#c26571");
equationText.push(epi);
var other = makeText("COOL EQUATION 3", eqX + 6, height - eqY - 1, 15);
other.color("#a0e3b9");
equationText.push(other);
var radius1 = makeText("Radius 1", eqX * 2, eqY, 18);
radius1.color(0);
buttonText.push(radius1);
radius2 = makeText("Radius 2", rad2X, eqY, 18);
radius2.color("#3f807e");
buttonText.push(radius2);
lineLen = makeText("Line Length", llX, eqY, 18);
lineLen.color("#65cdca");
buttonText.push(lineLen);
}
function drawText() {
textAlign(LEFT);
// change color pallete based on math equation
if (e === 1) { // purple-pink: epitrochoid
lineLen.color("#c26571");
radius2.color("#753d45")
}
else if (e === 2) {
lineLen.color("#a0e3b9");
radius2.color("#3d5747");
}
// draw the button's text
for (var t = 0; t < buttonText.length; t++) {
buttonText[t].draw();
}
}
function radiusSliders() {
ellipseMode(CENTER);
stroke(sliderCol);
strokeWeight(3);
// radius 1
line(r1Min, ry, r1Max, ry);
noStroke();
fill(0);
r1x = constrain(r1x, r1Min, r1Max);
ellipse(r1x, ry, rd, rd);
textAlign(CENTER);
r1Num = floor(map(r1x, r1Min, r1Max, radMin, rad1Max));
text(str(r1Num), r1x, ry + 2 * rd);
// radius 2
stroke(sliderCol);
strokeWeight(3);
line(r2Min, ry, r2Max, ry);
noStroke();
fill(0);
r2x = constrain(r2x, r2Min, r2Max);
ellipse(r2x, ry, rd, rd);
r2Num = floor(map(r2x, r2Min, r2Max, radMin, rad2Max));
text(str(r2Num), r2x, ry + 2 * rd);
// line length
stroke(sliderCol);
strokeWeight(3);
line(pMin, ry, pMax, ry);
noStroke();
fill(0);
px = constrain(px, pMin, pMax);
ellipse(px, ry, rd, rd);
lineNum = floor(map(px, pMin, pMax, llMin, llMax));
text(str(lineNum), px, ry + 2 * rd);
// radii can't be same size
if (r1Num === r2Num) {
diffRadii = false;
}
else {
diffRadii = true;
}
}
// button for the user to chose their pen color
function chooseColor() {
stroke(0);
strokeWeight(2);
fill(userCol);
rect(colorX, colorY, eqY, eqY);
}
function gradient() {
//gradient red to orange
for (var r = 0; r < gradSection; r += 2) {
var startR = color(255, 0, 0); // red
var endO = color(255, colorMid, 0); // orange
for (var c = 0; c < height; c += 2) {
var interCol1 = lerpColor(startR, endO, r/(width/6));
var white = color(255);
var interLight1 = lerpColor(interCol1, white, c/height);
fill(interLight1);
rect(r, c, 2, 2);
}
}
// gradient orange to yellow
for (var r = 0; r < gradSection; r += 2) {
var startO = color(255, colorMid, 0); // orange
var endY = color(255, 255, 0); // yellow
for (var c = 0; c < height; c += 2) {
var interCol2 = lerpColor(startO, endY, r/(width/6));
var interLight2 = lerpColor(interCol2, white, c/height);
fill(interLight2);
rect(r + gradSection, c, 2, 2);
}
}
// gradient yellow to green
for (var r = 0; r < gradSection; r += 2) {
var startY = color(255, 255, 0); // yellow
var endG = color(0, 255, 0); // green
for (var c = 0; c < height; c += 2) {
var interCol3 = lerpColor(startY, endG, r/(width/6));
var interLight3 = lerpColor(interCol3, white, c/height);
fill(interLight3);
rect(r + 2 * gradSection, c, 2, 2);
}
}
// gradient green to blue
for (var r = 0; r < gradSection; r += 2) {
var startG = color(0, 255, 0); // green
var endB = color(0, 0, 255); // blue
for (var c = 0; c < height; c += 2) {
var interCol4 = lerpColor(startG, endB, r/(width/6));
var interLight4 = lerpColor(interCol4, white, c/height);
fill(interLight4);
rect(r + 3 * gradSection, c, 2, 2);
}
}
// gradient blue to purple
for (var r = 0; r < gradSection; r += 2) {
var startB = color(0, 0, 255); // blue
var endPp = color(colorMid, 0, colorMid); // purple
for (var c = 0; c < height; c += 2) {
var interCol5 = lerpColor(startB, endPp, r/(width/6));
var interLight5 = lerpColor(interCol5, white, c/height);
fill(interLight5);
rect(r + 4 * gradSection, c, 2, 2);
}
}
// gradient purple to pink
for (var r = 0; r < gradSection; r += 2) {
var startPp = color(colorMid, 0, colorMid); // purple
var endPk = color(255, eqX, colorPink); // pink
for (var c = 0; c < height; c += 2) {
var interCol6 = lerpColor(startPp, endPk, r/(width/6));
var interLight6 = lerpColor(interCol6, white, c/height);
fill(interLight6);
rect(r + 5 * gradSection, c, 2, 2);
}
}
}
function displayEquation() {
// switch between the 2 equations
if (equationCount % 3 === 1) {
e = 0; // spirograph
}
else if (equationCount % 3 === 2) {
e = 1; // Epitrochoid
}
else if (equationCount % 3 === 0) {
e = 2;
}
// draw the equation name
eText = equationText[e];
fill(eText.tColor);
textSize(eText.size);
text(eText.t, eText.x, eText.y);
}
// back button to setting screen
function drawBackButton() {
var backButton = makeButton(backB, backB, backB, backB, "ellipse");
backButton.color(0);
noStroke();
backButton.draw();
stroke(255);
strokeWeight(2);
// arrow
line(backBX, backB, backB, backB + 8);
line(backBX, backB, backB, backBX + 1);
line(backBX, backB, backB + 9, backB);
}
// Object: Creates Buttons
function makeButton(bx, by, bw, bh, bShape) {
var button = {x: bx, y: by, bColor: color(0),
shape: bShape, w: bw, h: bh,
draw: displayButton, color: setbColor}
return button
}
// draws the buttons
function displayButton() {
fill(this.bColor);
if (this.shape == "rect") {
rect(this.x, this.y, this.w, this.h);
}
else if (this.shape === "ellipse") {
ellipse(this.x, this.y, this.w, this.h);
}
}
// sets the button color
function setbColor(c) {
this.bColor = color(c);
}
// Object: Creates text
function makeText(input, tx, ty, tSize) {
var textForButton = {x: tx, y: ty, size: tSize, tColor: color(backCol),
t: input, draw: displayText, color: setTColor}
return textForButton;
}
// draw the text
function displayText() {
fill(this.tColor);
textSize(this.size);
text(this.t, this.x, this.y);
}
// set the text color
function setTColor(c) {
this.tColor = color(c);
}
function mousePressed() {
// click draw button to go to draw mode
if ((mouseX > 7/9 * width) & (mouseX < 7/9 * width + 80)
&& (mouseY > 6/7 * height) && (mouseY < 6/7 * height + 30)
&& (drawing == false) && (diffRadii)) {
drawing = ! drawing;
justClicked = true;
}
// back button -- send to settings screen
else if (dist(mouseX, mouseY, backB, backB) <= backB / 2) {
drawing = false;
}
// 3 math equations -- button to rotate the math equations
else if ((mouseX > eqX) & (mouseX < eqX + eqW)
&& (mouseY > 7/8 * height) && (mouseY < 7/8 * height + eqY - 5)
&& (drawing == false)) {
equationCount += 1;
}
// drag radius 1 slider
if (dist(r1x, ry, mouseX, mouseY) < rd / 2) {
dragging = true;
rad1 = true;
justClicked = false;
drawing = false;
}
// drag radius 2 slider
else if (dist(r2x, ry, mouseX, mouseY) < rd / 2) {
dragging = true;
rad2 = true;
justClicked = false;
drawing = false;
}
// drag line length slider
else if (dist(px, ry, mouseX, mouseY) < rd / 2) {
print("t");
dragging = true;
lineL = true;
justClicked = false;
drawing = false;
}
// click inside color box
if ((mouseX <= colorX + eqY) & (mouseX >= colorX)
&& (mouseY <= colorY + eqY) && (mouseY >= colorY)
&& drawing === false) {
choosing = true;
}
// set pen color to user's click
if (choosing) {
userCol = color(get(mouseX, mouseY));
}
}
function mouseReleased() {
dragging = false;
rad1 = false;
rad2 = false;
lineL = false;
}
function keyPressed() {
// use left arrow key to go back to the settings screen
if ((drawing) & (keyCode === LEFT_ARROW)) {
drawing = false;
}
// set pen color by hitting enter key
if ((choosing) & (keyCode === ENTER)) {
choosing = false;
}
}
Steven Fei & Mike Jin – Final Project
Please refer to Mike Jin’s latest post
Sean Meng-Final Project
//Sean Meng
//hmeng@andrew.cmu.edu
//Section C
//Final Project
var mySoundA;
var amp;
var vol = [];
function preload() {
//Load music Love Lockdown
mySoundA = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/Love_Lockdown-online-audio-converter.com.wav");
mySoundA.setVolume(2);
}
function setup() {
createCanvas(500, 500);
//define amplitude and frequency to visualize
amplitude = new p5.Amplitude();
fft = new p5.FFT();
mySoundA.amp(0.2);
frameRate(200);
}
function draw() {
//size of the button
var bSize = 20;
background(218, 227, 226);
noStroke();
//Album art background
fill(250);
rect(0, 0, 100, 500);
fill(128, 15, 120);
rect(85, 0, 15, 45);
fill(34, 32, 99);
rect(85, 45, 15, 45);
fill(242, 235, 97);
rect(85, 90, 15, 45);
fill(141, 214, 204);
rect(85, 135, 15, 45);
fill(92, 182, 224);
rect(85, 180, 15, 45);
fill(53, 156, 120);
rect(85, 225, 15, 45);
fill(242, 182, 241);
rect(85, 270, 15, 45);
fill(197, 204, 124);
rect(85, 315, 15, 45);
fill(181, 103, 180);
rect(85, 360, 15, 45);
fill(184, 44, 116);
rect(85, 405, 15, 45);
fill(49, 6, 92);
rect(85, 450, 15, 50);
//PAUSE button
fill(0);
rect(10, height - 30, bSize, bSize);
//PLAY button
fill(0);
triangle(10, height - 60, 10, height - 40, 30, height - 50);
//Spectrum represents amplitude
let spectrum = fft.analyze();
noStroke();
fill(255);
for (var i = 0; i< spectrum.length; i++){
let x4 = map(i, 0, spectrum.length, 100, width * 3.5);
let h4 = -height + map(spectrum[i], 0, 255, height * 0.95, 0);
rect(x4, height, width / spectrum.length, h4 )
}
//Beating heart graphic represents amplitude
let level = amplitude.getLevel();
let offset = map(level, 0, 1, 0, 80);
//draw first half of the heart
strokeWeight(2);
stroke(220, 30, 30);
fill(220, 30, 30);
beginShape();
vertex(240 - offset, 180 - offset);
vertex(270 - offset, 165 - offset);
vertex(300, 180 - offset);
vertex(330 + offset, 160 - offset);
vertex(355 + offset, 170 - offset);
vertex(375 + offset, 200);
vertex(355 + offset, 240);
vertex(330 + offset, 270);
vertex(290, 335 + offset);
vertex(275 - offset, 280);
vertex(240 - offset, 240);
vertex(220 - offset, 210);
vertex(240 - offset, 180 - offset);
endShape();
//Draw second half of the heart
strokeWeight(2);
stroke(115, 20, 15);
fill(115, 20, 15);
beginShape();
vertex(300, 180 - offset);
vertex(330 + offset, 160 - offset);
vertex(355 + offset, 170 - offset);
vertex(375 + offset, 200);
vertex(355 + offset, 240);
vertex(330 + offset, 270);
vertex(290, 335 + offset);
vertex(305 + offset, 270);
vertex(290 - offset, 245);
vertex(300 + offset, 215);
vertex(275 - offset, 200);
vertex(300, 180 - offset);
endShape();
//Five waveform that visualzie frequency
//wave A
let waveform = fft.waveform();
noFill();
beginShape(POINTS);
stroke(150, 10, 10);
strokeWeight(2);
for(var i = 0; i < waveform.length; i++){
let x0 = map(i, 0, waveform.length, 100, width);
let y0 = map(waveform[i], - 3, 3, 0, height);
vertex(x0, y0);
}
endShape();
//wave B
beginShape(POINTS);
stroke(180, 10, 10);
strokeWeight(2);
for(var i = 0; i < waveform.length; i++){
let x0 = map(i, 0, waveform.length, 100, width);
let y0 = map(waveform[i], - 1.5, 1.5, 0, height);
vertex(x0, y0);
}
endShape();
//Wave C
beginShape(POINTS);
stroke(220, 30, 30);
strokeWeight(2);
for(var i = 0; i < waveform.length; i++){
let x1 = map(i, 0, waveform.length, 100, width);
let y1 = map(waveform[i], - 0.7, 0.7, 0, height);
vertex(x1, y1);
}
endShape();
//Wave D
beginShape(POINTS);
stroke(230, 50, 50);
strokeWeight(1);
for(var i = 0; i < waveform.length; i++){
let x2 = map(i, 0, waveform.length, 100, width);
let y2 = map(waveform[i], - 0.4, 0.4, 0, height);
vertex(x2, y2);
}
endShape();
//Wave E
beginShape(POINTS);
stroke(230, 90, 90);
strokeWeight(0.5);
for(var i = 0; i < waveform.length; i++){
let x2 = map(i, 0, waveform.length, 100, width);
let y2 = map(waveform[i], - 0.2, 0.2, 0, height);
vertex(x2, y2);
}
endShape();
//Title of the album
push();
translate(75, 250);
rotate(- PI / 2);
stroke(65);
fill(65);
textStyle(BOLDITALIC);
textSize(25);
text('808s & Heartbreaks', 0, 0);
pop();
}
function mousePressed() {
//play the song when buttonA is clicked
if(mouseX > 10 & mouseX < 30 && mouseY > height - 60 && mouseY < height - 40){
mySoundA.play();
}
//pause the song when buttonB is clicked
if(mouseX > 10 & mouseX < 30 && mouseY > height - 30 && mouseY < height - 10){
mySoundA.pause();
}
}
In this project, I intend to homage to my favorite artist of all time Kanye West. The project represents a visualization of his song Love Lockdown from his renowned album 808’s & Heartbreaks. The representation and graphic elements are inspired by the original album cover that designed by artist Kaws. While the beating heart visualizes the amplitude of the music, the waveforms which has a gradient of both color and stroke weight visualizes the frequency of the song. As the song goes, the frequency gets increasingly complicated and generates intriguing pattern.