xxxxxxxxxx
85
let butterflies = []; // initialize butterfly array
let maxLength; // initialize a maximum size for the array, used to prevent overcrowding of objects on the screen
function setup() {
createCanvas(600, 600);
background(0,10); // setup the background to the color black with 10% opacity
maxLength = 16; // set the maximum size to 8 objects per frame
butterflies.push(new Butterfly(random(0, width), random(0, height)));
}
function draw() {
background(0, 10); // clear the previous sketch with a thin black background with low opacity
for (let i = 0; i < butterflies.length; i++) { // display the butterflies in the array
// draw each butterfly object
butterflies[i].drawButterfly();
// remove the butterfly object if its drawing is finished
if (butterflies[i].finished()) {
butterflies.splice(i, 1);
// add a random butterfly to the sketch if the size of the array did not reach the
// maximum size
if (butterflies.length < maxLength){
butterflies.push(new Butterfly(random(0, width), random(0, height)));
}
}
}
}
class Butterfly {
constructor(x, y) {
this.x = x; // starting x location
this.y = y; // starting y location
this.theta = 0; // current drawing angle
// choose a random color from the color palette for the butterfly animation
this.color = random([
color("#7c9eb7"),
color("#c5d6db"),
color("#ffd3d7"),
color("#ffc20c"),
]);
// controlling hyperparameters for the butterfly shape
this.b = random(3, 6);
this.a = random([4, 6]);
// variable controlling the rotation of the object
this.angleRot = random([-1, 1]) * random([0, 1, 2, 3, 4]);
}
drawButterfly() {
push(); // save the current drawing state
translate(this.x, this.y); // move the origin to the object's position
stroke(this.color); // set the stroke color based on the chosen color
rotate((this.angleRot * PI) / 4); // rotate the object
noFill();
strokeWeight(1);
beginShape();
// draw the curve
for (let i = 0; i <= this.theta; i += 0.01) {
// calculate the radius based on the parameteric equation for the butterfly curve
let r =
exp(sin(i)) -
this.a * cos(4 * i) +
pow(sin((1 / this.b) * 12 * (2 * i - PI)), 5);
// calculate x and y position of the curve
let x = r * cos(i) * 30 * noise(i, frameCount*0.01);
let y = r * sin(i) * 30 * noise(i, frameCount*0.01);
// draw circle
curveVertex(x, y, r);
}
endShape();
this.theta += 0.01; // increment theta for animation
pop(); // restore original sketch state
}
finished() {
return this.theta > TWO_PI; // to indicate the end of the shape
}
}
function mousePressed() {
// add object at the location of the mouse if pressed
butterflies.push(new Butterfly(mouseX, mouseY));
}