Source of: Flow Field Particles, by Claude Opus 4.7
87 lines, no comments ยท 1,180 tokens, written in 13 seconds for $0.031
1 let particles = [];
2 let flowfield;
3 let cols, rows;
4 const scl = 20;
5 let zoff = 0;
6 let hueOffset = 0;
7
8 function setup() {
9 createCanvas(800, 600);
10 colorMode(HSB, 360, 100, 100, 100);
11 background(0);
12 cols = floor(width / scl);
13 rows = floor(height / scl);
14 flowfield = new Array(cols * rows);
15 for (let i = 0; i < 300; i++) {
16 particles.push(new Particle());
17 }
18 }
19
20 function draw() {
21 noStroke();
22 fill(0, 0, 0, 4);
23 rect(0, 0, width, height);
24
25 let yoff = 0;
26 for (let y = 0; y < rows; y++) {
27 let xoff = 0;
28 for (let x = 0; x < cols; x++) {
29 const index = x + y * cols;
30 const angle = noise(xoff, yoff, zoff) * TWO_PI * 2;
31 const v = p5.Vector.fromAngle(angle);
32 v.setMag(0.4);
33 flowfield[index] = v;
34 xoff += 0.1;
35 }
36 yoff += 0.1;
37 }
38 zoff += 0.003;
39 hueOffset += 0.2;
40
41 for (const p of particles) {
42 p.follow(flowfield);
43 p.update();
44 p.edges();
45 p.show();
46 }
47 }
48
49 class Particle {
50 constructor() {
51 this.pos = createVector(random(width), random(height));
52 this.vel = createVector(0, 0);
53 this.acc = createVector(0, 0);
54 this.maxSpeed = 2.5;
55 this.prev = this.pos.copy();
56 this.h = random(360);
57 }
58 follow(vectors) {
59 const x = floor(this.pos.x / scl);
60 const y = floor(this.pos.y / scl);
61 const index = x + y * cols;
62 const force = vectors[index];
63 if (force) this.acc.add(force);
64 }
65 update() {
66 this.vel.add(this.acc);
67 this.vel.limit(this.maxSpeed);
68 this.pos.add(this.vel);
69 this.acc.mult(0);
70 }
71 show() {
72 stroke((this.h + hueOffset) % 360, 80, 100, 40);
73 strokeWeight(1.3);
74 line(this.pos.x, this.pos.y, this.prev.x, this.prev.y);
75 this.updatePrev();
76 }
77 updatePrev() {
78 this.prev.x = this.pos.x;
79 this.prev.y = this.pos.y;
80 }
81 edges() {
82 if (this.pos.x > width) { this.pos.x = 0; this.updatePrev(); }
83 if (this.pos.x < 0) { this.pos.x = width; this.updatePrev(); }
84 if (this.pos.y > height) { this.pos.y = 0; this.updatePrev(); }
85 if (this.pos.y < 0) { this.pos.y = height; this.updatePrev(); }
86 }
87 }