├── style.css
├── readme.md
├── index.html
└── particles.js
/style.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | margin:0;
4 | padding:0;
5 | }
6 |
7 | canvas {
8 | background-color: #000;
9 | }
10 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # JS Particles
2 |
3 | ## Example
4 |
5 | - [http://orangespaceman.github.io/js-particles](http://orangespaceman.github.io/js-particles)
6 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | JS Particles
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/particles.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Particles
3 | */
4 | (function () {
5 |
6 | "use strict";
7 |
8 | /*
9 | * global variables
10 | */
11 | var
12 | // HTML canvas element
13 | canvas,
14 |
15 | // canvas draw context
16 | ctx,
17 |
18 | // collection of existing particles
19 | particles = [],
20 |
21 | // configurable options
22 | config = {
23 |
24 | // number of particles to draw
25 | particleCount : 50,
26 |
27 | // minimum distance for each particle to affect another
28 | minimumAffectingDistance : 50
29 | };
30 |
31 | /*
32 | * init
33 | */
34 | function init () {
35 | drawCanvas();
36 | createParticles();
37 | loop();
38 |
39 | // resize canvas on page resize
40 | window.addEventListener("resize", function (event) {
41 | drawCanvas();
42 | });
43 | }
44 |
45 |
46 | /*
47 | * start redraw loop logic
48 | */
49 | function loop () {
50 | clear();
51 | update();
52 | draw();
53 | queue();
54 | }
55 |
56 | /*
57 | * wipe canvas ready for next redraw
58 | */
59 | function clear () {
60 | ctx.clearRect(0, 0, canvas.width, canvas.height);
61 | }
62 |
63 | /*
64 | * update particle positions
65 | */
66 | function update () {
67 |
68 | // update each particle's position
69 | for (var count = 0; count < particles.length; count++) {
70 |
71 | var p = particles[count];
72 |
73 | // Change the velocities
74 | p.x += p.vx;
75 | p.y += p.vy;
76 |
77 | // Bounce a particle that hits the edge
78 | if(p.x + p.radius > canvas.width || p.x - p.radius < 0) {
79 | p.vx = -p.vx;
80 | }
81 |
82 | if(p.y + p.radius > canvas.height || p.y - p.radius < 0) {
83 | p.vy = -p.vy;
84 | }
85 |
86 | // Check particle attraction
87 | for (var next = count + 1; next < particles.length; next++) {
88 | var p2 = particles[next];
89 | calculateDistanceBetweenParticles(p, p2);
90 | }
91 | }
92 | }
93 |
94 | /*
95 | * update visual state - draw each particle
96 | */
97 | function draw () {
98 | for (var count = 0; count < particles.length; count++) {
99 | var p = particles[count];
100 | p.draw();
101 | }
102 | }
103 |
104 | /*
105 | * prepare next redraw when the browser is ready
106 | */
107 | function queue () {
108 | window.requestAnimationFrame(loop);
109 | }
110 |
111 | // go!
112 | init();
113 |
114 |
115 | /*
116 | * Objects
117 | */
118 |
119 | /*
120 | * Particle
121 | */
122 | function Particle () {
123 |
124 | // Position particle
125 | this.x = Math.random() * canvas.width;
126 | this.y = Math.random() * canvas.height;
127 |
128 | // Give particle velocity, between -1 and 1
129 | this.vx = -1 + Math.random() * 2;
130 | this.vy = -1 + Math.random() * 2;
131 |
132 | // Give particle a radius
133 | this.radius = 4;
134 |
135 | // draw particle
136 | this.draw = function () {
137 | ctx.fillStyle = "white";
138 | ctx.beginPath();
139 | ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
140 | ctx.fill();
141 | }
142 | }
143 |
144 | /*
145 | * Draw canvas
146 | */
147 | function drawCanvas () {
148 | canvas = document.querySelector("canvas");
149 | ctx = canvas.getContext("2d");
150 |
151 | // set canvas to full page dimensions
152 | canvas.width = window.innerWidth;
153 | canvas.height = window.innerHeight;
154 | }
155 |
156 | /*
157 | * Create particles
158 | */
159 | function createParticles () {
160 | for(var i = 0; i < config.particleCount; i++) {
161 | particles.push(new Particle());
162 | }
163 | }
164 |
165 |
166 | /*
167 | * Distance calculator between two particles
168 | */
169 | function calculateDistanceBetweenParticles (p1, p2) {
170 |
171 | var dist,
172 | dx = p1.x - p2.x,
173 | dy = p1.y - p2.y;
174 |
175 | dist = Math.sqrt(dx*dx + dy*dy);
176 |
177 | // Check whether distance is smaller than the min distance
178 | if(dist <= config.minimumAffectingDistance) {
179 |
180 | // set line opacity
181 | var opacity = 1 - dist/config.minimumAffectingDistance;
182 |
183 | // Draw connecting line
184 | ctx.beginPath();
185 | ctx.strokeStyle = "rgba(255, 255, 255, " + opacity +")";
186 | ctx.moveTo(p1.x, p1.y);
187 | ctx.lineTo(p2.x, p2.y);
188 | ctx.stroke();
189 | ctx.closePath();
190 |
191 | // Calculate particle acceleration
192 | var ax = dx / 2000,
193 | ay = dy / 2000;
194 |
195 | // Apply particle acceleration
196 | p1.vx -= ax;
197 | p1.vy -= ay;
198 |
199 | p2.vx += ax;
200 | p2.vy += ay;
201 | }
202 | }
203 | })();
204 |
--------------------------------------------------------------------------------