let rows, offset, margin, rowSize;
let pallete = ["#4D6F83", "#B1B0B1", "#278DD3", "#F8B623", "#3C494F", "#D51311", "#02020C"];
colorMode(HSB, 360, 100, 100, 100);
rows = int(random(5, 15));
rowSize = (height + offset * 2 - margin * (rows - 1)) / rows;
for (let i = 0; i < rows; i++) {
let y = -offset + i * (rowSize + margin);
if (i % 2 == 0) xPlus = rowSize / 2;
for (let x = -offset + xPlus; x < width + offset + xPlus; x += rowSize * 2) {
let angle = map(sin((x + y * width) / 5), -1, 1, 0, 180);
let sp = new SpringSystem(x, y, rowSize, rowSize, angle);
for (let sp of springSystems) {
if (frameCount % 250 == 0) {
constructor(x, y, w, h, angle) {
let c1 = random(pallete);
let c2 = random(pallete);
while (c1 == c2) c2 = random(pallete);
this.spring = new Spring(x + w / 2, y, min(w, h), c1);
let xx = x + w / 2 + cos(angle) * min(w, h) / 2;
let yy = y + sin(angle) * min(w, h) / 2;
this.bob = new Bob(xx, yy, c2);
this.minLength = min(w, h) * 1.5;
let gravity = createVector(0, 2);
this.bob.applyForce(gravity);
this.spring.connect(this.bob);
this.spring.constrainLength(this.bob, 30, 400);
this.spring.displayLine(this.bob);
this.position = createVector(x, y);
this.velocity = createVector();
this.acceleration = createVector();
this.mass = random(4,16);
this.dragOffset = createVector();
this.velocity.add(this.acceleration);
this.velocity.mult(this.damping);
this.position.add(this.velocity);
this.acceleration.mult(0);
drawingContext.shadowColor =color(0,0,0,50);
drawingContext.shadowBlur = this.mass;
drawingContext.shadowOffsetY = this.mass/2;
circle(this.position.x, this.position.y, this.mass * 2);
this.acceleration.add(f);
constructor(x, y, length, c) {
this.anchor = createVector(x, y);
this.restLength = length;
let force = p5.Vector.sub(bob.position, this.anchor);
let stretch = d - this.restLength;
force.mult(-1 * this.k * stretch);
constrainLength(b, minLength, maxLength) {
let dir = p5.Vector.sub(b.position, this.anchor);
b.position = p5.Vector.add(this.anchor, dir);
} else if (d > maxLength) {
b.position = p5.Vector.add(this.anchor, dir);
ellipse(this.anchor.x, this.anchor.y, 10);
line(b.position.x, b.position.y, this.anchor.x, this.anchor.y);