xxxxxxxxxx
659
let canvasSize = 600;
let scaleFactor = 1.5;
let scaledSize = canvasSize * scaleFactor;
//eye variables
let eyeOpen = false;
let blinkFrames = 0;
let doubleBlink = false;
//cat variables
let catList = [];
//controls whether we want to show cats or not
let showCat = true;
let catShownX = [4.8, -4, -10];
let catShownY = [5.45, -3, -7];
let catHiddenX = [-1, 2, 0];
let catHiddenY = [5, -16, 10];
let catMoveStep = 0.1;
// function that moves cats to desired location
function moveCats(directionArrayX, directionArrayY, stepLength) {
let maxDist = -1;
for (let i = 0; i < catList.length; i++) {
//only move each cat if distance is greater than error margin
if (
dist(
catList[i].x,
catList[i].y,
directionArrayX[i],
directionArrayY[i]
) >= 0.1
) {
let direction = createVector(
directionArrayX[i] - catList[i].x,
directionArrayY[i] - catList[i].y
);
direction.setMag(stepLength);
catList[i].x += direction.x;
catList[i].y += direction.y;
}
//calculate maximum distance from desired position and current position for each cat
maxDist = max(
maxDist,
dist(catList[i].x, catList[i].y, directionArrayX[i], directionArrayY[i])
);
}
}
function hideCats(stepLength) {
moveCats(catHiddenX, catHiddenY, stepLength);
}
function revealCats(stepLength) {
moveCats(catShownX, catShownY, stepLength);
}
class Cat {
constructor(
x,
y,
angle,
baseColor,
eyeColor,
mouthColor = color(255),
noseColor = color(202, 137, 155)
) {
this.x = x;
this.y = y;
this.angle = angle;
this.baseColor = baseColor;
this.eyeColor = eyeColor;
this.noseColor = noseColor;
this.mouthColor = mouthColor;
}
show() {
push();
translate(scaledSize / this.x, scaledSize / this.y);
rotate(this.angle);
strokeWeight(2);
//face
push();
fill(this.baseColor);
triangle(
-scaledSize / 25,
-scaledSize / 120,
-scaledSize / 21.81,
-scaledSize / 17.14,
-scaledSize / 100,
-scaledSize / 26.66
);
triangle(
scaledSize / 25,
-scaledSize / 120,
scaledSize / 21.81,
-scaledSize / 17.14,
scaledSize / 100,
-scaledSize / 26.66
);
circle(0, 0, scaledSize / 12);
pop();
// eyes
push();
strokeWeight(2);
fill(255);
circle(-scaledSize / 60, -scaledSize / 120, scaledSize / 40);
circle(scaledSize / 60, -scaledSize / 120, scaledSize / 40);
pop();
push();
noStroke();
fill(this.eyeColor);
circle(-scaledSize / 60, -scaledSize / 120, scaledSize / 48);
circle(scaledSize / 60, -scaledSize / 120, scaledSize / 48);
pop();
push();
noStroke();
fill(this.noseColor);
triangle(
0,
scaledSize / 120,
-scaledSize / 150,
scaledSize / 300,
scaledSize / 150,
scaledSize / 300
);
pop();
//mouth
push();
stroke(this.mouthColor);
strokeWeight(1);
line(0, scaledSize / 120, 0, scaledSize / 80);
pop();
push();
stroke(this.mouthColor);
strokeWeight(1);
translate(-scaledSize / 1200, scaledSize / 80);
rotate(PI / 3);
line(0, 0, 0, scaledSize / 120);
pop();
push();
stroke(this.mouthColor);
strokeWeight(1);
translate(scaledSize / 1200, scaledSize / 80);
rotate(-PI / 3);
line(0, 0, 0, scaledSize / 120);
pop();
pop();
}
}
function setup() {
let canvas = createCanvas(canvasSize, canvasSize);
rectMode(CENTER);
//adding the cats
if(!showCat)
{
//black cat
catList.push(
new Cat(catHiddenX[0], catHiddenY[0], PI / 6, color(0), color(0, 100, 180))
);
// grey cat
catList.push(
new Cat(
catHiddenX[1],
catHiddenY[1],
PI,
color(100),
color(100, 0, 34),
color(0)
)
);
//orange cat
catList.push(
new Cat(
catHiddenX[2],
catHiddenY[2],
-PI / 3.5,
color(255, 155, 64),
color(118, 99, 22),
color(0),
color(207, 100, 67)
)
);
}
else {
//black cat
catList.push(
new Cat(catShownX[0],
catShownY[0],
PI / 6, color(0),
color(0, 100, 180))
);
// grey cat
catList.push(
new Cat(
catShownX[1],
catShownY[1],
PI,
color(100),
color(100, 0, 34),
color(0)
)
);
//orange cat
catList.push(
new Cat(
catShownX[2],
catShownY[2],
-PI / 3.5,
color(255, 155, 64),
color(118, 99, 22),
color(0),
color(207, 100, 67)
)
);
}
}
function draw() {
background(20, 32, 53);
translate(width / 2, height / 2 + 30);
strokeWeight(2);
fill(243, 185, 147);
//cat
if (showCat)
// reveal the cats
revealCats(catMoveStep);
else hideCats(catMoveStep);
// display the cats
for (let i = 0; i < catList.length; i++) {
catList[i].show();
}
//ears
//left ear
push();
translate(-scaledSize / 10, -scaledSize / 80);
rotate(-PI / 20);
ellipse(0, 0, scaledSize / 40, scaledSize / 13.33);
pop();
//right ear
push();
translate(scaledSize / 10, -scaledSize / 80);
rotate(PI / 20);
ellipse(0, 0, scaledSize / 40, scaledSize / 13.33);
pop();
//hair
push();
stroke(30, 15, 15);
strokeWeight(3);
fill(30, 15, 15);
arc(0, -scaledSize / 14.28, scaledSize / 4.44, scaledSize / 4.21, -PI, 0);
pop();
//shirt
push();
fill(103, 39, 56);
stroke(0);
strokeWeight(2);
circle(-scaledSize / 8, scaledSize / 2.92, scaledSize / 3.09);
circle(scaledSize / 8, scaledSize / 2.92, scaledSize / 3.09);
noStroke();
rect(0, scaledSize / 2.85, scaledSize / 4, scaledSize / 2.92);
// stroke(1)
rect(0, scaledSize / 2.1, scaledSize / 1.745, scaledSize / 4);
stroke(0);
strokeWeight(2);
line(-scaledSize / 8, scaledSize / 5.55, scaledSize / 8, scaledSize / 5.55);
line(
-scaledSize / 3.49,
scaledSize / 2,
-scaledSize / 3.49,
scaledSize / 2.86
);
line(scaledSize / 3.49, scaledSize / 2, scaledSize / 3.49, scaledSize / 2.86);
line(scaledSize / 5.33, scaledSize / 2, scaledSize / 5.33, scaledSize / 2.85);
line(
-scaledSize / 5.33,
scaledSize / 2,
-scaledSize / 5.33,
scaledSize / 2.86
);
pop();
//face and neck are relative to canvas size
//neck
push();
rect(0, scaledSize / 7.2, scaledSize / 7, scaledSize / 8, scaledSize / 40);
arc(0, scaledSize / 5.6, scaledSize / 7, scaledSize / 9, 0, PI);
pop();
//shadow on neck
push();
noStroke();
fill(166, 126, 100);
arc(0, scaledSize / 13, scaledSize / 7, scaledSize / 7, 0, PI);
pop();
//face
push();
rect(
0,
-scaledSize / 26,
scaledSize / 5,
scaledSize / 3.9,
scaledSize / 6.6,
scaledSize / 6.6
);
arc(0, 0, scaledSize / 5, scaledSize / 3.7, 0, PI);
pop();
//nose
push();
fill(192, 146, 116);
stroke(0);
strokeWeight(2);
//nostril triangle
triangle(
0,
0,
-scaledSize / 40,
scaledSize / 26.67,
scaledSize / 40,
scaledSize / 26.67
);
//base triangle
triangle(
0,
-scaledSize / 40,
-scaledSize / 66.67,
scaledSize / 26.67,
scaledSize / 66.67,
scaledSize / 26.67
);
pop();
push();
noStroke();
fill(144, 86, 76);
//upper lip
triangle(
-scaledSize / 80,
scaledSize / 17.78,
-scaledSize / 80 - scaledSize / 40,
scaledSize / 15.38,
-scaledSize / 80 + scaledSize / 40,
scaledSize / 15.38
);
triangle(
scaledSize / 80,
scaledSize / 17.78,
scaledSize / 80 - scaledSize / 40,
scaledSize / 15.38,
scaledSize / 80 + scaledSize / 40,
scaledSize / 15.38
);
//lower lip color
fill(203, 134, 128);
//lower lip
arc(0, scaledSize / 14.035, scaledSize / 21, scaledSize / 100, 0, PI);
pop();
//mole
push();
fill(0);
circle(-scaledSize / 50, scaledSize / 57.14, scaledSize / 1000);
pop();
// eyes
//blink animation
if (eyeOpen) {
if (frameCount % 150 == 0) eyeOpen = !eyeOpen;
} else {
blinkFrames++;
if (blinkFrames % 11 == 0) {
eyeOpen = !eyeOpen;
}
}
//closed eyes
if (!eyeOpen) {
push();
fill(204, 155, 123);
arc(
scaledSize / 20,
-scaledSize / 40,
scaledSize / 22.86,
scaledSize / 32,
0,
PI
);
arc(
-scaledSize / 20,
-scaledSize / 40,
scaledSize / 22.86,
scaledSize / 32,
0,
-PI
);
pop();
//left eyelashes
line(
-scaledSize / 27.27,
-scaledSize / 90,
-scaledSize / 30,
-scaledSize / 128.57
);
line(
-scaledSize / 20,
-scaledSize / 112.5,
-scaledSize / 20,
-scaledSize / 300
);
line(
-scaledSize / 16.36,
-scaledSize / 90,
-scaledSize / 15,
-scaledSize / 128.57
);
//right eyelashes
line(
scaledSize / 27.27,
-scaledSize / 90,
scaledSize / 30,
-scaledSize / 128.57
);
line(
scaledSize / 20,
-scaledSize / 112.5,
scaledSize / 20,
-scaledSize / 300
);
line(
scaledSize / 16.36,
-scaledSize / 90,
scaledSize / 15,
-scaledSize / 128.57
);
} else {
//open eyes
push();
//eyeball
fill(255);
arc(
scaledSize / 20,
-scaledSize / 40,
scaledSize / 22.86,
scaledSize / 32,
0,
PI,
CHORD
);
arc(
-scaledSize / 20,
-scaledSize / 40,
scaledSize / 22.86,
scaledSize / 32,
0,
-PI,
CHORD
);
//iris
stroke(0);
strokeWeight(1);
fill(73, 31, 15);
arc(
scaledSize / 20,
-scaledSize / 42,
scaledSize / 50,
scaledSize / 34.78,
0,
-PI,
CHORD
);
arc(
-scaledSize / 20,
-scaledSize / 42,
scaledSize / 50,
scaledSize / 34.78,
0,
-PI,
CHORD
);
//pupil
stroke(0);
fill(0);
circle(scaledSize / 20, -scaledSize / 53, scaledSize / 160);
circle(-scaledSize / 20, -scaledSize / 53, scaledSize / 160);
pop();
}
//eyebrows
push();
//right eyebrow
beginShape();
stroke(0);
fill(0);
curveVertex(scaledSize / 40, -scaledSize / 22.22);
curveVertex(scaledSize / 16, -scaledSize / 21.05);
curveVertex(scaledSize / 12.31, -scaledSize / 24.24);
curveVertex(scaledSize / 16, -scaledSize / 25);
curveVertex(scaledSize / 40, -scaledSize / 25);
endShape(CLOSE);
pop();
push();
//left eyebrow
beginShape();
stroke(0);
fill(0);
curveVertex(-scaledSize / 40, -scaledSize / 22.22);
curveVertex(-scaledSize / 16, -scaledSize / 21.05);
curveVertex(-scaledSize / 12.31, -scaledSize / 24.24);
curveVertex(-scaledSize / 16, -scaledSize / 25);
curveVertex(-scaledSize / 40, -scaledSize / 25);
endShape(CLOSE);
pop();
//hair
push();
stroke(30, 15, 15);
strokeWeight(3);
fill(30, 15, 15);
triangle(
-scaledSize / 10,
-scaledSize / 160,
-scaledSize / 10.67,
-scaledSize / 11.43,
-scaledSize / 8.89,
-scaledSize / 14.55
);
triangle(
scaledSize / 10,
-scaledSize / 160,
scaledSize / 10.67,
-scaledSize / 11.436,
scaledSize / 8.89,
-scaledSize / 14.55
);
push();
translate(-scaledSize / 15.38, -scaledSize / 7.55);
rotate(-PI / 3.2);
ellipse(0, 0, scaledSize / 9.41, scaledSize / 53.33);
rotate(PI / 3.6);
rotate(-PI / 4);
ellipse(0, 0, scaledSize / 8, scaledSize / 40);
pop();
push();
translate(scaledSize / 15.38, -scaledSize / 7.55);
rotate(PI / 3.2);
ellipse(0, 0, scaledSize / 9.41, scaledSize / 53.33);
rotate(-PI / 3.6);
rotate(PI / 4);
ellipse(0, 0, scaledSize / 8, scaledSize / 40);
pop();
//forehead covering hair
rect(0, -scaledSize / 5.84, scaledSize / 13.33, scaledSize / 61.54);
rect(0, -scaledSize / 6.96, scaledSize / 7.27, scaledSize / 26.67);
rect(0, -scaledSize / 8, scaledSize / 7.27, scaledSize / 80);
pop();
push();
stroke(30, 15, 15);
strokeWeight(3);
fill(30, 15, 15);
triangle(
-scaledSize / 10.13,
-scaledSize / 20,
-scaledSize / 12.31,
-scaledSize / 9.41,
-scaledSize / 9.09,
-scaledSize / 14.545
);
triangle(
scaledSize / 10.13,
-scaledSize / 20,
scaledSize / 12.31,
-scaledSize / 9.41,
scaledSize / 9.09,
-scaledSize / 14.55
);
pop();
}
function mouseClicked() {
showCat = !showCat;
}
function keyTyped() {
if (key === "s") {
saveCanvas(canvas, "screenshot", "jpg");
}
}