ichthyarchy: The domain of fishes; the fish-world in all of its orders.
Reference:
Saved .png image:
Twelve swimming Fish
objects are instantiated when the sketch is loaded. For each Fish
, the initial location, direction of swim, and drawing order are randomly calculated. Small random factors modify the horizontal velocity and vertical drift of each Fish
as it swims.
Click the sketch to stop and start the animation.
p5.js code:
new p5((p) => {
let school = [];
let anim = true;
p.setup = () => {
p.createCanvas(p.windowWidth, p.windowHeight);
p.noStroke();
p.ellipseMode(p.CENTER);
p.textFont("Verdana");
p.textSize(48);
p.textAlign(p.CENTER, p.CENTER);
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
200,
60,
p.color(128, 255, 128),
p.random(["left", "right"])
)
); // green
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
160,
80,
p.color(128, 128, 255),
p.random(["left", "right"])
)
); // blue
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
200,
60,
p.color(255, 128, 128),
p.random(["left", "right"])
)
); // red
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
160,
80,
p.color(255, 255, 128),
p.random(["left", "right"])
)
); // yellow
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
200,
60,
p.color(255, 128, 255),
p.random(["left", "right"])
)
); // magenta
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
160,
80,
p.color(128, 255, 255),
p.random(["left", "right"])
)
); // cyan
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
240,
40,
p.color(184, 115, 51),
p.random(["left", "right"])
)
); // copper
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
280,
40,
p.color(192, 192, 192),
p.random(["left", "right"])
)
); // silver
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
240,
40,
p.color(255, 215, 0),
p.random(["left", "right"])
)
); // gold
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
240,
40,
p.color(255, 165, 0),
p.random(["left", "right"])
)
); // orange
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
280,
40,
p.color(166, 10, 61),
p.random(["left", "right"])
)
); // cranberry
school.push(
new Fish(
p.random(p.width),
p.random(p.height),
240,
40,
p.color(128, 128, 0),
p.random(["left", "right"])
)
); // olive
p.shuffle(school, true);
p.background(187, 221, 255);
for (let i = 0; i < school.length; i++) {
school[i].render();
}
p.fill(0, 64);
p.text("ichthyarchy", p.width / 2, 48);
};
p.draw = () => {
p.background(187, 221, 255);
if (anim) {
for (let i = 0; i < school.length; i++) {
school[i].swim();
}
} else {
for (let i = 0; i < school.length; i++) {
school[i].render();
}
}
p.fill(0, 64);
p.text("ichthyarchy", p.width / 2, 48);
};
p.windowResized = () => {
p.resizeCanvas(p.windowWidth, p.windowHeight);
};
class Fish {
constructor(x, y, bodyLength, bodyHeight, c, chirality) {
this.x = x;
this.y = y;
this.bodyLength = bodyLength;
this.bodyHeight = bodyHeight;
this.c = c;
if (chirality == "right") {
this.chirality = 1;
} else {
this.chirality = -1;
}
} // end constructor
swim() {
let dx;
let dy;
dx = (p.abs(p.randomGaussian() * 2) + 2) * this.chirality;
dy = p.randomGaussian() / 2;
// (p.height / 2 - this.y) / 100;
this.x += dx;
this.y += dy;
// horizontal correction
if (this.x > p.width + this.bodyLength / 2) {
this.x = -this.bodyLength / 2;
}
if (this.x < -this.bodyLength / 2) {
this.x = p.width + this.bodyLength / 2;
}
// vertical correction
if (this.y > p.height - this.bodyHeight / 2) {
this.y = p.height - this.bodyHeight / 2 - 1;
}
if (this.y < this.bodyHeight / 2) {
this.y = this.bodyHeight / 2 + 1;
}
this.render();
} // end swim
render() {
// Body
p.noStroke();
p.fill(this.c);
p.ellipse(this.x, this.y, this.bodyLength, this.bodyHeight);
p.triangle(
this.x - (this.chirality * this.bodyLength) / 16,
this.y,
this.x - (this.chirality * this.bodyLength) / 2,
this.y + this.bodyHeight / 2,
this.x - (this.chirality * this.bodyLength) / 2,
this.y - this.bodyHeight / 2
);
p.triangle(
this.x,
this.y,
this.x - this.bodyLength / 4,
this.y - this.bodyHeight / 2,
this.x + this.bodyLength / 4,
this.y - this.bodyHeight / 2
);
p.triangle(
this.x,
this.y,
this.x - this.bodyLength / 4,
this.y + this.bodyHeight / 2,
this.x + this.bodyLength / 4,
this.y + this.bodyHeight / 2
);
p.fill(32);
p.circle(
this.x + (this.chirality * this.bodyLength) / 4,
this.y,
this.bodyHeight / 8
);
} // end render
} // end class Fish
const toggleAnimation = () => {
anim = !anim;
};
document.addEventListener("click", toggleAnimation, true);
});