xxxxxxxxxx
105
// Colors taken from https://jasonheglund.com/the-coding-train-expansion
const colors = [
['#f063a5', '#70327f'], // Semicolon pink
['#f89f4f', '#701616'], // Equals orange
['#fdee21', '#0b6a8a'], // Asterisk yelllow
['#2dc5f4', '#0b6985'], // Angle bracket blue
['#fdee21', '#d17329'], // Zero yellow
['#9254a1', '#6f317e'], // This. purple
['#f16063', '#701616'], // Square red
['#f89f4f', '#5a3314'], // Triangle orange
['#f063a5', '#a52a63'], // Curly bracket pink
];
colors.sort(() => Math.random() - 0.5);
// Defines a circle in terms of its bend (curvature) and center point
class Circle {
constructor(bend, x, y, depth = 0) {
// Center is stored as a Complex number
this.center = new Complex(x, y);
this.bend = bend;
// Radius is derived from the absolute value of the reciprocal of bend
this.radius = abs(1 / this.bend);
// The depth is also the generation number
this.depth = depth;
// Select a color based on the depth
this.col = colors[this.depth % colors.length];
this.surprisedTimer = 0;
}
show() {
const fillColor = this.col[0];
const strokeColor = this.col[1];
stroke(strokeColor);
// noFill();
fill(fillColor);
// Draws the circle with its center at (a, b) and diameter of radius * 2
strokeWeight(1);
circle(this.center.a, this.center.b, this.radius * 2);
const mouthRadius = this.radius / 5;
// Draws the mouth, if the circle is surprised draw a full arc
noFill();
strokeWeight(mouthRadius / 4);
arc(this.center.a, this.center.b + mouthRadius * 2,
mouthRadius * 2, mouthRadius * 2,
0, this.surprisedTimer > 0 ? TWO_PI : PI);
// Decrease the surprised timer by deltaTime
if (this.surprisedTimer > 0){
this.surprisedTimer -= deltaTime;
}
const eyeRadius = this.radius / 5;
const eyeOffset = eyeRadius*2;
const pupilRadius = eyeRadius / 2;
// Define all eyes
const eyePositions = [
createVector(this.center.a - eyeOffset, this.center.b), // Left eye
createVector(this.center.a + eyeOffset, this.center.b), // Right eye
// createVector(this.center.a, this.center.b - eyeOffset), // Third eye
];
// Draw all eyes
for(const eyePosition of eyePositions){
// Draw the iris
fill(strokeColor);
noStroke();
ellipse(eyePosition.x, eyePosition.y, eyeRadius * 2, eyeRadius * 3);
// To get the pupil position first get the eyePosition
const pupilPosition = eyePosition.copy();
// Than get a vector from the pupilPosition to the mouse
const mouseOffset = p5.Vector.sub(createVector(mouseX, mouseY), pupilPosition);
// Limit the vector to never exceed the eye
mouseOffset.limit(eyeRadius - pupilRadius);
// Offset the pupilPosition by the mouseOffset
pupilPosition.add(mouseOffset);
// Draw the pupil
fill(255);
circle(pupilPosition.x, pupilPosition.y, pupilRadius * 2);
}
}
mousePressed(){
// If the mouse is over make this circle surprised
if(dist(mouseX, mouseY, this.center.a, this.center.b) < this.radius){
this.surprisedTimer = 700;
return true;
}
return false;
}
// Computes the distance between this circle and another circle
dist(other) {
return dist(this.center.a, this.center.b, other.center.a, other.center.b);
}
}