Source of: Drifting Ink Flow Field, by Claude Opus 5.5
89 lines, no comments ยท 1,361 tokens, written in 18 seconds for $0.029
1 let particles = [];
2 const NUM = 2500;
3 let zoff = 0;
4 let seedVal;
5
6 function setup() {
7 createCanvas(windowWidth, windowHeight);
8 colorMode(HSB, 360, 100, 100, 100);
9 reseed();
10 }
11
12 function reseed() {
13 seedVal = floor(random(100000));
14 noiseSeed(seedVal);
15 background(230, 40, 8);
16 particles = [];
17 for (let i = 0; i < NUM; i++) {
18 particles.push(new Particle());
19 }
20 }
21
22 function draw() {
23 noStroke();
24 fill(230, 40, 8, 4);
25 rect(0, 0, width, height);
26 zoff += 0.0015;
27 for (const p of particles) {
28 p.update();
29 p.show();
30 }
31 }
32
33 class Particle {
34 constructor() {
35 this.reset();
36 }
37 reset() {
38 this.pos = createVector(random(width), random(height));
39 this.prev = this.pos.copy();
40 this.vel = createVector(0, 0);
41 this.life = random(100, 400);
42 this.hueOff = random(-25, 25);
43 }
44 update() {
45 const scl = 0.0025;
46 const n = noise(this.pos.x * scl, this.pos.y * scl, zoff);
47 const angle = n * TWO_PI * 4;
48 const force = p5.Vector.fromAngle(angle).mult(0.35);
49 this.vel.add(force);
50 if (mouseIsPressed === false) {
51 const d = dist(mouseX, mouseY, this.pos.x, this.pos.y);
52 if (d < 120 && d > 0.1) {
53 const away = createVector(this.pos.x - mouseX, this.pos.y - mouseY);
54 away.setMag(map(d, 0, 120, 1.5, 0));
55 this.vel.add(away);
56 }
57 }
58 this.vel.limit(2.5);
59 this.prev.set(this.pos);
60 this.pos.add(this.vel);
61 this.life--;
62 if (this.life < 0 || this.pos.x < 0 || this.pos.x > width || this.pos.y < 0 || this.pos.y > height) {
63 this.reset();
64 }
65 }
66 show() {
67 const n = noise(this.pos.x * 0.001, this.pos.y * 0.001, zoff * 2);
68 const h = (map(n, 0, 1, 160, 340) + this.hueOff + frameCount * 0.1) % 360;
69 stroke(h, 70, 95, 25);
70 strokeWeight(1.2);
71 line(this.prev.x, this.prev.y, this.pos.x, this.pos.y);
72 }
73 }
74
75 function mousePressed() {
76 reseed();
77 }
78
79 function keyPressed() {
80 if (key === 's' || key === 'S') {
81 saveCanvas('flowfield_' + seedVal, 'png');
82 }
83 }
84
85 function windowResized() {
86 resizeCanvas(windowWidth, windowHeight);
87 background(230, 40, 8);
88 }
89