Source of: Neon Particle Vortex, by GPT Chat Latest
144 lines, no comments · 1,404 tokens, written in 8 seconds for $0.043
1 let particles = [];
2 const COUNT = 650;
3
4 function setup() {
5 createCanvas(windowWidth, windowHeight);
6 colorMode(HSB, 360, 100, 100, 100);
7 background(235, 35, 5);
8 for (let i = 0; i < COUNT; i++) {
9 particles.push(new Particle());
10 }
11 }
12
13 function draw() {
14 background(235, 35, 5, 12);
15
16 let t = frameCount * 0.004;
17 let cx = width / 2;
18 let cy = height / 2;
19
20 push();
21 noFill();
22 strokeWeight(1);
23 for (let i = 0; i < 5; i++) {
24 let r = 35 + i * 24 + sin(t * 2 + i) * 7;
25 stroke((190 + i * 25 + frameCount * 0.3) % 360, 75, 90, 13);
26 circle(cx, cy, r * 2);
27 }
28 pop();
29
30 for (let p of particles) {
31 p.update(t);
32 p.display();
33 }
34
35 noStroke();
36 for (let i = 5; i > 0; i--) {
37 fill((190 + frameCount * 0.5) % 360, 80, 100, 5);
38 circle(cx, cy, i * 19);
39 }
40 fill(190, 30, 100, 90);
41 circle(cx, cy, 8);
42
43 fill(0, 0, 100, 45);
44 textAlign(CENTER);
45 textSize(12);
46 text('MOVE TO DISTORT • CLICK TO BURST', width / 2, height - 25);
47 }
48
49 class Particle {
50 constructor() {
51 this.reset();
52 this.angle = random(TWO_PI);
53 this.radius = random(30, max(width, height) * 0.65);
54 }
55
56 reset() {
57 this.angle = random(TWO_PI);
58 this.radius = random(10, 60);
59 this.speed = random(0.003, 0.014);
60 this.outward = random(0.15, 0.7);
61 this.size = random(0.8, 3.2);
62 this.hue = random(165, 310);
63 this.offset = random(1000);
64 this.x = width / 2;
65 this.y = height / 2;
66 this.px = this.x;
67 this.py = this.y;
68 }
69
70 update(t) {
71 this.px = this.x;
72 this.py = this.y;
73
74 this.angle += this.speed * (1 + 70 / (this.radius + 30));
75 this.radius += this.outward;
76
77 let wave = sin(this.angle * 4 + t * 2 + this.offset) * 18;
78 let r = this.radius + wave;
79
80 let stretch = min(width, height) * 0.1;
81 this.x = width / 2 + cos(this.angle) * r * 1.25;
82 this.y = height / 2 + sin(this.angle) * r * 0.75 + sin(this.angle * 2 + t) * stretch * 0.2;
83
84 if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {
85 let dx = this.x - mouseX;
86 let dy = this.y - mouseY;
87 let d = sqrt(dx * dx + dy * dy);
88 if (d < 180 && d > 1) {
89 let force = pow(1 - d / 180, 2) * 85;
90 this.x += dx / d * force;
91 this.y += dy / d * force;
92 }
93 }
94
95 if (this.radius > max(width, height) * 0.8 ||
96 this.x < -100 || this.x > width + 100 ||
97 this.y < -100 || this.y > height + 100) {
98 this.reset();
99 }
100 }
101
102 display() {
103 let h = (this.hue + frameCount * 0.13) % 360;
104 let alpha = map(this.radius, 0, max(width, height) * 0.8, 85, 15);
105
106 stroke(h, 85, 100, alpha * 0.25);
107 strokeWeight(this.size * 4);
108 point(this.x, this.y);
109
110 stroke(h, 65, 100, alpha);
111 strokeWeight(this.size);
112 line(this.px, this.py, this.x, this.y);
113
114 noStroke();
115 fill(h, 30, 100, alpha);
116 circle(this.x, this.y, this.size * 0.8);
117 }
118 }
119
120 function mousePressed() {
121 for (let p of particles) {
122 let dx = p.x - mouseX;
123 let dy = p.y - mouseY;
124 let d = sqrt(dx * dx + dy * dy);
125 if (d < 300) {
126 p.radius += random(20, 120) * (1 - d / 300);
127 p.angle += random(-0.5, 0.5);
128 p.hue = random(170, 330);
129 }
130 }
131 }
132
133 function touchStarted() {
134 if (touches.length > 0) {
135 mousePressed();
136 }
137 return false;
138 }
139
140 function windowResized() {
141 resizeCanvas(windowWidth, windowHeight);
142 background(235, 35, 5);
143 }
144