Source of: Orbiting Particles Flow Field, by GPT-5.1
74 lines, 7 of them comments ยท 658 tokens, written in 6 seconds for $0.0067
1 let particles = [];
2 let numParticles = 400;
3
4 function setup() {
5 createCanvas(windowWidth, windowHeight);
6 colorMode(HSB, 360, 100, 100, 100);
7 background(0);
8 for (let i = 0; i < numParticles; i++) {
9 particles.push(new Particle());
10 }
11 }
12
13 function draw() {
14 // Fade the background slightly to create trails
15 noStroke();
16 fill(0, 0, 0, 10);
17 rect(0, 0, width, height);
18
19 // Update and display particles
20 for (let p of particles) {
21 p.update();
22 p.show();
23 }
24 }
25
26 class Particle {
27 constructor() {
28 this.pos = createVector(random(width), random(height));
29 this.vel = p5.Vector.random2D().mult(random(0.2, 1));
30 this.acc = createVector(0, 0);
31 this.maxSpeed = random(1, 3);
32 this.h = random(360);
33 this.size = random(2, 4);
34 }
35
36 update() {
37 // Attraction towards mouse, weaker with distance
38 let target = createVector(mouseX, mouseY);
39 let force = p5.Vector.sub(target, this.pos);
40 let distSq = constrain(force.magSq(), 50, 80000);
41 force.setMag(2 / sqrt(distSq)); // Inverse distance falloff
42
43 // Add slight perpendicular component to create orbit-like motion
44 let orbit = createVector(-force.y, force.x);
45 orbit.setMag(0.02);
46
47 this.acc.add(force).add(orbit);
48
49 this.vel.add(this.acc);
50 this.vel.limit(this.maxSpeed);
51 this.pos.add(this.vel);
52 this.acc.mult(0);
53
54 // Wrap around edges
55 if (this.pos.x < 0) this.pos.x = width;
56 if (this.pos.x > width) this.pos.x = 0;
57 if (this.pos.y < 0) this.pos.y = height;
58 if (this.pos.y > height) this.pos.y = 0;
59
60 // Slowly cycle hue
61 this.h = (this.h + 0.4) % 360;
62 }
63
64 show() {
65 stroke(this.h, 80, 100, 80);
66 strokeWeight(this.size);
67 point(this.pos.x, this.pos.y);
68 }
69 }
70
71 function windowResized() {
72 resizeCanvas(windowWidth, windowHeight);
73 background(0);
74 }