Source of: Luminous Currents, by GPT-6.1 Sol
93 lines, no comments ยท 1,113 tokens, written in 17 seconds for $0.011
1 let particles = [];
2 let paused = false;
3 let time = 0;
4 const COUNT = 1000;
5
6 function setup() {
7 createCanvas(windowWidth, windowHeight);
8 pixelDensity(min(displayDensity(), 2));
9 colorMode(HSB, 360, 100, 100, 1);
10 resetSketch();
11 }
12
13 function resetSketch() {
14 background(230, 65, 5);
15 noiseSeed(floor(random(100000)));
16 time = 0;
17 particles = Array.from({ length: COUNT }, () => ({
18 x: random(width),
19 y: random(height),
20 vx: 0,
21 vy: 0,
22 speed: random(1.1, 2.8),
23 hue: random(165, 285)
24 }));
25 }
26
27 function draw() {
28 if (paused) return;
29
30 noStroke();
31 fill(230, 65, 5, 0.065);
32 rect(0, 0, width, height);
33
34 const dt = min(deltaTime / 16.667, 2);
35 time += 0.002 * dt;
36 strokeWeight(1.15);
37
38 for (const p of particles) {
39 const oldX = p.x;
40 const oldY = p.y;
41 const angle = noise(p.x * 0.0025, p.y * 0.0025, time) * TWO_PI * 3;
42 let fx = cos(angle) * p.speed;
43 let fy = sin(angle) * p.speed;
44
45 if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
46 const dx = mouseX - p.x;
47 const dy = mouseY - p.y;
48 const distance = sqrt(dx * dx + dy * dy);
49 if (distance > 1 && distance < 210) {
50 const influence = (1 - distance / 210) * 5;
51 if (mouseIsPressed) {
52 fx += dx / distance * influence;
53 fy += dy / distance * influence;
54 } else {
55 fx += -dy / distance * influence;
56 fy += dx / distance * influence;
57 }
58 }
59 }
60
61 p.vx = lerp(p.vx, fx, 0.09 * dt);
62 p.vy = lerp(p.vy, fy, 0.09 * dt);
63 p.x += p.vx * dt;
64 p.y += p.vy * dt;
65
66 let wrapped = false;
67 if (p.x < 0) { p.x = width; wrapped = true; }
68 if (p.x > width) { p.x = 0; wrapped = true; }
69 if (p.y < 0) { p.y = height; wrapped = true; }
70 if (p.y > height) { p.y = 0; wrapped = true; }
71
72 if (!wrapped) {
73 const hue = (p.hue + 28 * sin(time + p.y * 0.003) + 360) % 360;
74 stroke(hue, 65, 100, 0.48);
75 line(oldX, oldY, p.x, p.y);
76 }
77 }
78 }
79
80 function keyPressed() {
81 if (key === ' ') {
82 paused = !paused;
83 return false;
84 }
85 if (key === 'r' || key === 'R') resetSketch();
86 if (key === 's' || key === 'S') saveCanvas('luminous-currents', 'png');
87 }
88
89 function windowResized() {
90 resizeCanvas(windowWidth, windowHeight);
91 resetSketch();
92 }
93