Source of: Neon Quantum Drift, by Gemini 4 Argon
111 lines, no comments ยท 1,160 tokens, written in 25 seconds for $0.012
1 let particles = [];
2 const numParticles = 1200;
3 let noiseScale = 0.004;
4 let time = 0;
5 let hueOffset = 0;
6
7 function setup() {
8 createCanvas(windowWidth, windowHeight);
9 colorMode(HSB, 360, 100, 100, 100);
10 background(240, 30, 5);
11
12 for (let i = 0; i < numParticles; i++) {
13 particles.push(new Particle());
14 }
15 }
16
17 function draw() {
18 blendMode(BLEND);
19 noStroke();
20 fill(240, 30, 5, 8);
21 rect(0, 0, width, height);
22
23 blendMode(ADD);
24
25 for (let p of particles) {
26 p.update();
27 p.display();
28 }
29
30 time += 0.003;
31 hueOffset = (hueOffset + 0.2) % 360;
32 }
33
34 class Particle {
35 constructor() {
36 this.init();
37 }
38
39 init() {
40 this.pos = createVector(random(width), random(height));
41 this.prevPos = this.pos.copy();
42 this.vel = createVector(0, 0);
43 this.acc = createVector(0, 0);
44 this.maxSpeed = random(2, 5);
45 this.hue = random(60);
46 this.size = random(1, 3.5);
47 }
48
49 update() {
50 this.prevPos = this.pos.copy();
51
52 let n = noise(this.pos.x * noiseScale, this.pos.y * noiseScale, time);
53 let angle = n * TWO_PI * 4;
54 let force = p5.Vector.fromAngle(angle);
55 force.mult(0.3);
56 this.acc.add(force);
57
58 if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
59 let mouse = createVector(mouseX, mouseY);
60 let dir = p5.Vector.sub(mouse, this.pos);
61 let d = dir.mag();
62 if (d < 200) {
63 dir.normalize();
64 let swirl = createVector(-dir.y, dir.x);
65 let strength = map(d, 0, 200, 1.5, 0);
66 swirl.mult(strength);
67 dir.mult(strength * 0.2);
68 this.acc.add(swirl);
69 this.acc.add(dir);
70 }
71 }
72
73 this.vel.add(this.acc);
74 this.vel.limit(this.maxSpeed);
75 this.pos.add(this.vel);
76 this.acc.mult(0);
77
78 this.edges();
79 }
80
81 display() {
82 let currentHue = (this.hue + hueOffset + (this.pos.x / width) * 120) % 360;
83 let speed = this.vel.mag();
84 let alpha = map(speed, 0, this.maxSpeed, 10, 60);
85
86 stroke(currentHue, 80, 90, alpha);
87 strokeWeight(this.size);
88 line(this.prevPos.x, this.prevPos.y, this.pos.x, this.pos.y);
89 }
90
91 edges() {
92 if (this.pos.x > width || this.pos.x < 0 || this.pos.y > height || this.pos.y < 0) {
93 this.pos = createVector(random(width), random(height));
94 this.prevPos = this.pos.copy();
95 }
96 }
97 }
98
99 function mousePressed() {
100 noiseSeed(millis());
101 hueOffset = (hueOffset + 90) % 360;
102 for (let p of particles) {
103 let burst = p5.Vector.random2D().mult(random(5, 15));
104 p.vel.add(burst);
105 }
106 }
107
108 function windowResized() {
109 resizeCanvas(windowWidth, windowHeight);
110 background(240, 30, 5);
111 }