Source of: Flow Field Particle Dance, by Claude Sonnet 5
109 lines, no comments ยท 1,321 tokens, written in 11 seconds for $0.014
1 let particles = [];
2 const numParticles = 1200;
3 let noiseScale = 0.008;
4 let zOffset = 0;
5 let hueShift = 0;
6
7 function setup() {
8 createCanvas(windowWidth, windowHeight);
9 colorMode(HSB, 360, 100, 100, 100);
10 background(10, 10, 15);
11 for (let i = 0; i < numParticles; i++) {
12 particles.push(new Particle());
13 }
14 }
15
16 function draw() {
17 background(10, 10, 15, 6);
18
19 hueShift += 0.15;
20
21 for (let p of particles) {
22 p.follow();
23 p.update();
24 p.edges();
25 p.show();
26 }
27
28 zOffset += 0.003;
29 }
30
31 class Particle {
32 constructor() {
33 this.pos = createVector(random(width), random(height));
34 this.vel = createVector(0, 0);
35 this.acc = createVector(0, 0);
36 this.maxSpeed = random(2, 4);
37 this.prevPos = this.pos.copy();
38 this.hue = random(360);
39 this.lifespan = random(200, 500);
40 this.age = 0;
41 }
42
43 follow() {
44 let angle = noise(
45 this.pos.x * noiseScale,
46 this.pos.y * noiseScale,
47 zOffset
48 ) * TWO_PI * 4;
49 let force = p5.Vector.fromAngle(angle);
50 force.setMag(0.15);
51 this.acc.add(force);
52 }
53
54 update() {
55 this.vel.add(this.acc);
56 this.vel.limit(this.maxSpeed);
57 this.pos.add(this.vel);
58 this.acc.mult(0);
59 this.age++;
60 if (this.age > this.lifespan) {
61 this.respawn();
62 }
63 }
64
65 respawn() {
66 this.pos = createVector(random(width), random(height));
67 this.prevPos = this.pos.copy();
68 this.age = 0;
69 this.lifespan = random(200, 500);
70 this.hue = (this.hue + random(30, 90)) % 360;
71 }
72
73 edges() {
74 if (this.pos.x > width) {
75 this.pos.x = 0;
76 this.prevPos = this.pos.copy();
77 }
78 if (this.pos.x < 0) {
79 this.pos.x = width;
80 this.prevPos = this.pos.copy();
81 }
82 if (this.pos.y > height) {
83 this.pos.y = 0;
84 this.prevPos = this.pos.copy();
85 }
86 if (this.pos.y < 0) {
87 this.pos.y = height;
88 this.prevPos = this.pos.copy();
89 }
90 }
91
92 show() {
93 let displayHue = (this.hue + hueShift) % 360;
94 stroke(displayHue, 70, 90, 50);
95 strokeWeight(1.2);
96 line(this.prevPos.x, this.prevPos.y, this.pos.x, this.pos.y);
97 this.prevPos = this.pos.copy();
98 }
99 }
100
101 function windowResized() {
102 resizeCanvas(windowWidth, windowHeight);
103 background(10, 10, 15);
104 }
105
106 function mousePressed() {
107 noiseScale = random(0.003, 0.015);
108 }
109