<!DOCTYPE html> <html lang="en-us"> <head> <meta charset="utf-8"> <meta name="robots" content="noindex"> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> <title>Poi Bounce</title> <style> html, body { height: 100%; display: flex; align-items: center; justify-content: center; background-color: #222; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.10.0/p5.js"></script> <!-- © Adam Murray 2025 https://adammurray.link/ Creative Commons License Attribution-NonCommercial-ShareAlike 4.0 International https://creativecommons.org/licenses/by-nc-sa/4.0/ --> <script> let balls = []; let increment = 0.035; let zoff = 0.0; let zincrement = 0.01; function setup() { const dim = Math.min(Math.min(600, windowWidth), windowHeight) - 60; createCanvas(dim, dim).parent("processing-canvas"); strokeWeight(2); smooth(); background(0); for (let i = 0; i < 20; i++) { balls[i] = new BouncingBall(); } } function draw() { drawBackground(); // the ground: stroke(0, 100, 0); strokeWeight(20); line(0, height - 1, width, height - 1); stroke(255, 120, 0, 70); strokeWeight(1); for (let i = 0; i < balls.length; i++) { balls[i].draw(); } } function drawBackground() { noStroke(); let xoff = 0.0; // Start xoff at 0 const xinc = random(7.0) + 13; const yinc = random(4.0) + 14; for (let x = -20; x < width; x += xinc) { xoff += increment; let yoff = 0.0; for (let y = -20; y < height; y += yinc) { yoff += increment; const b = noise(xoff, yoff, zoff) * 255; const r = noise(xoff, yoff, zoff * 2) * 100; fill(r, 0, b, 90); rect(x, y, 14, 17); } } zoff += zincrement; } class BouncingBall { // float x, y; // float v, a; // velocity and acceleration // int d; // ball diameter // boolean stopped; // int alpha; // int gcolor; // int bcolor; constructor() { this.v = 0; // velocity this.a = 0.8; // acceleration this.d = 25; // ball diameter this.init(); // create a random delay for the initial drop: this.stopped = true; this.alpha = int(random(255)); } init() { this.x = random(width); this.y = -2 * this.d; this.stopped = false; this.alpha = 235; this.gcolor = int(random(170) + 70); this.bcolor = int(random(170) + 70); } draw() { fill(240, this.gcolor, this.bcolor, this.alpha); ellipse(this.x, this.y, this.d, this.d); this.update(); } update() { if (this.stopped) { if (this.alpha > 0) { this.alpha--; return; } this.init(); } this.y += this.v; this.x += random(1.0) - 0.5; this.v += this.a; if (this.y > height - this.d) { this.v -= random(3.0) + this.v / 5.0; if (this.v < 0) { this.stopped = true; } this.v *= -1; this.y = height - this.d; } } } </script> </head> <body> <div id="processing-canvas"></div> </body> </html>