function getRemInPixels() { return parseFloat(getComputedStyle(document.documentElement).fontSize); } function getParticleCount() { return Math.floor(2 * Math.min(window.innerWidth, window.innerHeight)); } let canvas; let color0 = { }; let color1 = { r: 16, g: 65, b: 83 }; let color2 = { r: 82, g: 159, b: 164 }; let color3 = { r: 241, g: 210, b: 151 }; let color4 = { r: 210, g: 117, b: 62 }; let particles = []; let m = 5; let n = 4; let threshold = 0.05; let minMN = 1; let maxMN = 6; let changePattern = false; let margin = 50; let w1, w2, h1, h2; let scl = 1; let rem = getRemInPixels(); let xold; let yold; let num = getParticleCount(); // dynamic based on window size let resizeTimeout; class Particle { constructor() { this.position = createVector(random(w1, w2), random(h1, h2)); this.velocity = p5.Vector.random2D(); this.acceleration = createVector(); this.maxSpeed = 2; this.maxForce = 0.1; } edges() { if (this.position.x <= w1) { this.position.x = w1; this.velocity.x *= -1; } else if (this.position.x >= w2) { this.position.x = w2; this.velocity.x *= -1; } if (this.position.y <= h1) { this.position.y = h1; this.velocity.y *= -1; } else if (this.position.y >= h2) { this.position.y = h2; this.velocity.y *= -1; } } seek() { let x = map(this.position.x, w1, w2, -1, 1) * scl; let y = map(this.position.y, h1, h2, -1, 1) * scl; let val = chladni(x, y); let target = this.position.copy(); if (abs(val) > threshold) { target.x += random(-3, 3); target.y += random(-3, 3); } let desired = p5.Vector.sub(target, this.position); desired.setMag(this.maxSpeed); let steering = p5.Vector.sub(desired, this.velocity); steering.limit(this.maxForce); return steering; } update() { this.edges(); this.acceleration.add(this.seek()); this.velocity.add(this.acceleration); this.velocity.limit(this.maxSpeed); this.position.add(this.velocity); this.acceleration.mult(0); } display() { stroke(229, 107, 46); strokeWeight(0.2 * rem); point(this.position.x, this.position.y); } } function setup() { let parent = document.getElementById('hero-animation'); canvas = createCanvas(parent.offsetWidth, parent.offsetHeight); canvas.parent(parent); colorMode(RGB, 255, 255, 255, 1); frameRate(30); w = parent.offsetWidth; h = parent.offsetHeight; xold = w; yold = h; pixelDensity(1); w1 = 0.1 * rem; w2 = w - 0.1 * rem; h1 = 0.1 * rem; h2 = h - 0.1 * rem; for (let i=0; i { changePattern = true; }, 20000); } function draw() { clear(); background(255,255,255,0); if (changePattern) { randomPatterns(); } for (let i=0; i 0) { for (let i = 0; i < diff; i++) { particles.push(new Particle()); } } else if (diff < 0) { particles.splice(diff); // removes from the end } xold = w; yold = h; } function windowResized() { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(handleResize, 250); } window.addEventListener("orientationchange", () => { setTimeout(() => { handleResize(); // Trigger manually, with the delay logic inside }, 200); }); function chladni (x, y) { let L = 1; return cos(n * PI * x / L) * cos(m * PI * y / L) - cos(m * PI * x / L) * cos(n * PI * y / L); } function randomPatterns() { m = floor(random(minMN, maxMN)); n = floor(random(minMN, maxMN)); if (m === n) { m = floor(random(minMN, maxMN)); } changePattern = false; for (let i=0; i