Source of: Flowing Fields, by Claude Fable 5
78 lines, 2 of them comments ยท 1,061 tokens, written in 13 seconds for $0.056
1 let particles = [];
2 const NUM_PARTICLES = 900;
3 let noiseScale = 0.0035;
4 let hueBase;
5
6 function setup() {
7 createCanvas(windowWidth, windowHeight);
8 colorMode(HSB, 360, 100, 100, 100);
9 background(230, 40, 8);
10 hueBase = random(360);
11 for (let i = 0; i < NUM_PARTICLES; i++) {
12 particles.push(newParticle());
13 }
14 strokeWeight(1.2);
15 }
16
17 function newParticle() {
18 return {
19 x: random(width),
20 y: random(height),
21 px: 0,
22 py: 0,
23 life: random(100, 400),
24 speed: random(0.8, 2.2),
25 hueOff: random(-40, 40)
26 };
27 }
28
29 function draw() {
30 // very subtle fade for long trails
31 noStroke();
32 fill(230, 40, 8, 1.2);
33 rect(0, 0, width, height);
34
35 for (let p of particles) {
36 p.px = p.x;
37 p.py = p.y;
38
39 let n = noise(p.x * noiseScale, p.y * noiseScale, frameCount * 0.0015);
40 let angle = n * TWO_PI * 3;
41
42 p.x += cos(angle) * p.speed;
43 p.y += sin(angle) * p.speed;
44 p.life--;
45
46 let h = (hueBase + p.hueOff + n * 90) % 360;
47 if (h < 0) h += 360;
48 stroke(h, 70, 95, 28);
49 line(p.px, p.py, p.x, p.y);
50
51 if (p.life <= 0 || p.x < -10 || p.x > width + 10 || p.y < -10 || p.y > height + 10) {
52 let np = newParticle();
53 p.x = np.x;
54 p.y = np.y;
55 p.life = np.life;
56 p.speed = np.speed;
57 p.hueOff = np.hueOff;
58 }
59 }
60 }
61
62 function mousePressed() {
63 // reseed the field and palette on click
64 noiseSeed(floor(random(100000)));
65 hueBase = random(360);
66 background(230, 40, 8);
67 for (let p of particles) {
68 p.x = random(width);
69 p.y = random(height);
70 p.life = random(100, 400);
71 }
72 }
73
74 function windowResized() {
75 resizeCanvas(windowWidth, windowHeight);
76 background(230, 40, 8);
77 }
78