canvasparticles-js 3.2.13 → 3.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/canvasParticles.js +76 -66
- package/canvasParticles.mjs +76 -66
- package/package.json +30 -30
package/canvasParticles.js
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* Canvas Particles JS
|
|
6
6
|
*
|
|
7
7
|
* @class CanvasParticles
|
|
8
|
-
* @version 3.2.
|
|
8
|
+
* @version 3.2.14
|
|
9
9
|
*/
|
|
10
10
|
class CanvasParticles {
|
|
11
|
-
static version = '3.2.
|
|
11
|
+
static version = '3.2.14'
|
|
12
12
|
animating = false
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -153,9 +153,17 @@ class CanvasParticles {
|
|
|
153
153
|
speed: speed || (0.5 + Math.random() * 0.5) * this.options.particles.relSpeed, // Velocity in pixels per update
|
|
154
154
|
size: size || 0.5 + Math.random() ** 5 * 2 * this.options.particles.relSize, // Ray in pixels of the particle
|
|
155
155
|
})
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
const particle = this.particles.at(-1)
|
|
157
|
+
|
|
158
|
+
// Within these bounds the particle is considered visible
|
|
159
|
+
particle.bounds = {
|
|
160
|
+
top: -particle.size,
|
|
161
|
+
right: this.canvas.width + particle.size,
|
|
162
|
+
bottom: this.canvas.height + particle.size,
|
|
163
|
+
left: -particle.size,
|
|
164
|
+
}
|
|
165
|
+
particle.gridPos = this.gridPos(particle) // The location of the particle relative to the visible center of the canvas
|
|
166
|
+
particle.isVisible = particle.gridPos.x === 1 && particle.gridPos.y === 1
|
|
159
167
|
}
|
|
160
168
|
|
|
161
169
|
/**
|
|
@@ -173,71 +181,72 @@ class CanvasParticles {
|
|
|
173
181
|
for (let i = 0; i < len; i++) {
|
|
174
182
|
for (let j = i + 1; j < len; j++) {
|
|
175
183
|
// Code in this scope runs [particles ** 2 / 2] times!
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
const dist = Math.hypot(
|
|
179
|
-
const angle = Math.atan2(
|
|
184
|
+
const particleA = this.particles[i]
|
|
185
|
+
const particleB = this.particles[j]
|
|
186
|
+
const dist = Math.hypot(particleA.posX - particleB.posX, particleA.posY - particleB.posY)
|
|
187
|
+
const angle = Math.atan2(particleB.posY - particleA.posY, particleB.posX - particleA.posX)
|
|
180
188
|
|
|
181
189
|
if (dist < this.options.particles.connectDist / 2) {
|
|
182
190
|
// Apply repulsive force on all particles close together
|
|
183
191
|
const grav = (1 / Math.max(dist, 10)) ** 1.8 * gravRepulsiveMult
|
|
184
192
|
const gravX = Math.cos(angle) * grav
|
|
185
193
|
const gravY = Math.sin(angle) * grav
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
194
|
+
particleA.velX -= gravX
|
|
195
|
+
particleA.velY -= gravY
|
|
196
|
+
particleB.velX += gravX
|
|
197
|
+
particleB.velY += gravY
|
|
190
198
|
} else if (enabledPulling) {
|
|
191
199
|
// Apply pulling force on all particles not close together
|
|
192
200
|
const grav = (1 / Math.max(dist, 10)) ** 1.8 * gravPullingMult
|
|
193
201
|
const gravX = Math.cos(angle) * grav
|
|
194
202
|
const gravY = Math.sin(angle) * grav
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
203
|
+
particleA.velX += gravX
|
|
204
|
+
particleA.velY += gravY
|
|
205
|
+
particleB.velX -= gravX
|
|
206
|
+
particleB.velY -= gravY
|
|
199
207
|
}
|
|
200
208
|
}
|
|
201
209
|
}
|
|
202
210
|
}
|
|
203
211
|
|
|
204
|
-
for (let
|
|
212
|
+
for (let particle of this.particles) {
|
|
205
213
|
// Moving the particle
|
|
206
|
-
|
|
207
|
-
(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
214
|
+
particle.dir =
|
|
215
|
+
(particle.dir + Math.random() * this.options.particles.rotationSpeed * 2 - this.options.particles.rotationSpeed) % (2 * Math.PI)
|
|
216
|
+
particle.velX *= this.options.gravity.friction
|
|
217
|
+
particle.velY *= this.options.gravity.friction
|
|
218
|
+
particle.posX = (particle.posX + particle.velX + ((Math.sin(particle.dir) * particle.speed) % this.width) + this.width) % this.width
|
|
219
|
+
particle.posY =
|
|
220
|
+
(particle.posY + particle.velY + ((Math.cos(particle.dir) * particle.speed) % this.height) + this.height) % this.height
|
|
212
221
|
|
|
213
|
-
const distX =
|
|
214
|
-
const distY =
|
|
222
|
+
const distX = particle.posX + this.offX - this.mouseX
|
|
223
|
+
const distY = particle.posY + this.offY - this.mouseY
|
|
215
224
|
|
|
216
225
|
// Mouse events
|
|
217
226
|
if (this.options.mouse.interactionType !== 0) {
|
|
218
227
|
const distRatio = this.options.mouse.connectDist / Math.hypot(distX, distY)
|
|
219
228
|
|
|
220
229
|
if (this.options.mouse.distRatio < distRatio) {
|
|
221
|
-
|
|
222
|
-
|
|
230
|
+
particle.offX += (distRatio * distX - distX - particle.offX) / 4
|
|
231
|
+
particle.offY += (distRatio * distY - distY - particle.offY) / 4
|
|
223
232
|
} else {
|
|
224
|
-
|
|
225
|
-
|
|
233
|
+
particle.offX -= particle.offX / 4
|
|
234
|
+
particle.offY -= particle.offY / 4
|
|
226
235
|
}
|
|
227
236
|
}
|
|
228
|
-
|
|
229
|
-
|
|
237
|
+
particle.x = particle.posX + particle.offX
|
|
238
|
+
particle.y = particle.posY + particle.offY
|
|
230
239
|
|
|
231
240
|
if (this.options.mouse.interactionType === 2) {
|
|
232
241
|
// Make the mouse actually move the particles
|
|
233
|
-
|
|
234
|
-
|
|
242
|
+
particle.posX = particle.x
|
|
243
|
+
particle.posY = particle.y
|
|
235
244
|
}
|
|
236
|
-
|
|
237
|
-
|
|
245
|
+
particle.x += this.offX
|
|
246
|
+
particle.y += this.offY
|
|
238
247
|
|
|
239
|
-
|
|
240
|
-
|
|
248
|
+
particle.gridPos = this.gridPos(particle)
|
|
249
|
+
particle.isVisible = particle.gridPos.x === 1 && particle.gridPos.y === 1
|
|
241
250
|
}
|
|
242
251
|
}
|
|
243
252
|
|
|
@@ -255,34 +264,34 @@ class CanvasParticles {
|
|
|
255
264
|
* - { x: 1, y: 2 } = bottom
|
|
256
265
|
* - { x: 2, y: 2 } = bottom-right
|
|
257
266
|
*
|
|
258
|
-
* @param {Object}
|
|
259
|
-
* @param {number}
|
|
260
|
-
* @param {number}
|
|
267
|
+
* @param {Object} particle - The coordinates of the particle.
|
|
268
|
+
* @param {number} particle.x - The x-coordinate of the particle.
|
|
269
|
+
* @param {number} particle.y - The y-coordinate of the particle.
|
|
261
270
|
* @returns {Object} - The calculated grid position of the particle.
|
|
262
271
|
* @returns {number} x - The horizontal grid position (0, 1, or 2).
|
|
263
272
|
* @returns {number} y - The vertical grid position (0, 1, or 2).
|
|
264
273
|
*/
|
|
265
|
-
gridPos = function (
|
|
274
|
+
gridPos = function (particle) {
|
|
266
275
|
return {
|
|
267
|
-
x: (
|
|
268
|
-
y: (
|
|
276
|
+
x: (particle.x >= particle.bounds.left) + (particle.x > particle.bounds.right),
|
|
277
|
+
y: (particle.y >= particle.bounds.top) + (particle.y > particle.bounds.bottom),
|
|
269
278
|
}
|
|
270
279
|
}
|
|
271
280
|
|
|
272
281
|
/**
|
|
273
282
|
* Determines whether a line between 2 particles crosses through the visible center of the canvas.
|
|
274
|
-
* @param {Object}
|
|
275
|
-
* @param {Object}
|
|
283
|
+
* @param {Object} particleA - First particle with {gridPos, isVisible}.
|
|
284
|
+
* @param {Object} particleB - Second particle with {gridPos, isVisible}.
|
|
276
285
|
* @returns {boolean} - True if the line crosses the visible center, false otherwise.
|
|
277
286
|
*/
|
|
278
|
-
isLineVisible = function (
|
|
279
|
-
// Visible if either
|
|
280
|
-
if (
|
|
287
|
+
isLineVisible = function (particleA, particleB) {
|
|
288
|
+
// Visible if either particle is in the center
|
|
289
|
+
if (particleA.isVisible || particleB.isVisible) return true
|
|
281
290
|
|
|
282
|
-
// Not visible if both
|
|
291
|
+
// Not visible if both particles are in the same vertical or horizontal line but outside the center
|
|
283
292
|
return !(
|
|
284
|
-
(
|
|
285
|
-
(
|
|
293
|
+
(particleA.gridPos.x === particleB.gridPos.x && particleA.gridPos.x !== 1) ||
|
|
294
|
+
(particleA.gridPos.y === particleB.gridPos.y && particleA.gridPos.y !== 1)
|
|
286
295
|
)
|
|
287
296
|
}
|
|
288
297
|
|
|
@@ -295,24 +304,24 @@ class CanvasParticles {
|
|
|
295
304
|
this.ctx.fillStyle = this.options.particles.color + this.options.particles.opacity.hex
|
|
296
305
|
this.ctx.lineWidth = 1
|
|
297
306
|
|
|
298
|
-
for (let
|
|
299
|
-
if (
|
|
307
|
+
for (let particle of this.particles) {
|
|
308
|
+
if (particle.isVisible) {
|
|
300
309
|
// Draw the particle as a square if the size is smaller than 1 pixel (±183% faster than drawing only circles)
|
|
301
|
-
if (
|
|
310
|
+
if (particle.size > 1) {
|
|
302
311
|
// Draw circle
|
|
303
312
|
this.ctx.beginPath()
|
|
304
|
-
this.ctx.arc(
|
|
313
|
+
this.ctx.arc(particle.x, particle.y, particle.size, 0, 2 * Math.PI)
|
|
305
314
|
this.ctx.fill()
|
|
306
315
|
this.ctx.closePath()
|
|
307
316
|
} else {
|
|
308
317
|
// Draw square (±335% faster than circle)
|
|
309
|
-
this.ctx.fillRect(
|
|
318
|
+
this.ctx.fillRect(particle.x - particle.size, particle.y - particle.size, particle.size * 2, particle.size * 2)
|
|
310
319
|
}
|
|
311
320
|
}
|
|
312
321
|
}
|
|
313
322
|
|
|
314
323
|
const len = this.len
|
|
315
|
-
const drawAll = this.options.particles.connectDist >= Math.min(this.width, this.height)
|
|
324
|
+
const drawAll = this.options.particles.connectDist >= Math.min(this.canvas.width, this.canvas.height)
|
|
316
325
|
|
|
317
326
|
const maxWorkPerParticle = this.options.particles.connectDist * this.options.particles.maxWork
|
|
318
327
|
const maxWork = maxWorkPerParticle * len
|
|
@@ -323,16 +332,16 @@ class CanvasParticles {
|
|
|
323
332
|
|
|
324
333
|
for (let j = i + 1; j < len; j++) {
|
|
325
334
|
// Code in this scope runs [particles ** 2 / 2] times!
|
|
326
|
-
const
|
|
327
|
-
const
|
|
335
|
+
const particleA = this.particles[i]
|
|
336
|
+
const particleB = this.particles[j]
|
|
328
337
|
|
|
329
338
|
// Draw a line if its visible
|
|
330
|
-
if (this.isLineVisible(
|
|
331
|
-
const distX =
|
|
332
|
-
const distY =
|
|
339
|
+
if (this.isLineVisible(particleA, particleB) | drawAll) {
|
|
340
|
+
const distX = particleA.x - particleB.x
|
|
341
|
+
const distY = particleA.y - particleB.y
|
|
333
342
|
const dist = Math.sqrt(distX * distX + distY * distY)
|
|
334
343
|
|
|
335
|
-
// Connect the 2
|
|
344
|
+
// Connect the 2 particles with a line if the distance is small enough
|
|
336
345
|
if (dist < this.options.particles.connectDist) {
|
|
337
346
|
// Calculate the transparency of the line
|
|
338
347
|
if (dist >= this.options.particles.connectDist / 2) {
|
|
@@ -344,8 +353,8 @@ class CanvasParticles {
|
|
|
344
353
|
|
|
345
354
|
// Draw the line
|
|
346
355
|
this.ctx.beginPath()
|
|
347
|
-
this.ctx.moveTo(
|
|
348
|
-
this.ctx.lineTo(
|
|
356
|
+
this.ctx.moveTo(particleA.x, particleA.y)
|
|
357
|
+
this.ctx.lineTo(particleB.x, particleB.y)
|
|
349
358
|
this.ctx.stroke()
|
|
350
359
|
|
|
351
360
|
if ((work += dist) >= maxWork || (particleWork += dist) >= maxWorkPerParticle) break
|
|
@@ -407,6 +416,7 @@ class CanvasParticles {
|
|
|
407
416
|
} else {
|
|
408
417
|
// Example: extract 0.25 from rgba(136, 244, 255, 0.25) and convert to range 0x00 to 0xff and store as a 2 char string
|
|
409
418
|
const value = ~~(this.ctx.fillStyle.split(',').at(-1).slice(1, -1) * 255)
|
|
419
|
+
|
|
410
420
|
this.options.particles.opacity = {
|
|
411
421
|
value: value,
|
|
412
422
|
hex: value.toString(16),
|
package/canvasParticles.mjs
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* Canvas Particles JS
|
|
6
6
|
*
|
|
7
7
|
* @module CanvasParticles
|
|
8
|
-
* @version 3.2.
|
|
8
|
+
* @version 3.2.14
|
|
9
9
|
*/
|
|
10
10
|
export default class CanvasParticles {
|
|
11
|
-
static version = '3.2.
|
|
11
|
+
static version = '3.2.14'
|
|
12
12
|
animating = false
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -153,9 +153,17 @@ export default class CanvasParticles {
|
|
|
153
153
|
speed: speed || (0.5 + Math.random() * 0.5) * this.options.particles.relSpeed, // Velocity in pixels per update
|
|
154
154
|
size: size || 0.5 + Math.random() ** 5 * 2 * this.options.particles.relSize, // Ray in pixels of the particle
|
|
155
155
|
})
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
const particle = this.particles.at(-1)
|
|
157
|
+
|
|
158
|
+
// Within these bounds the particle is considered visible
|
|
159
|
+
particle.bounds = {
|
|
160
|
+
top: -particle.size,
|
|
161
|
+
right: this.canvas.width + particle.size,
|
|
162
|
+
bottom: this.canvas.height + particle.size,
|
|
163
|
+
left: -particle.size,
|
|
164
|
+
}
|
|
165
|
+
particle.gridPos = this.gridPos(particle) // The location of the particle relative to the visible center of the canvas
|
|
166
|
+
particle.isVisible = particle.gridPos.x === 1 && particle.gridPos.y === 1
|
|
159
167
|
}
|
|
160
168
|
|
|
161
169
|
/**
|
|
@@ -173,71 +181,72 @@ export default class CanvasParticles {
|
|
|
173
181
|
for (let i = 0; i < len; i++) {
|
|
174
182
|
for (let j = i + 1; j < len; j++) {
|
|
175
183
|
// Code in this scope runs [particles ** 2 / 2] times!
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
const dist = Math.hypot(
|
|
179
|
-
const angle = Math.atan2(
|
|
184
|
+
const particleA = this.particles[i]
|
|
185
|
+
const particleB = this.particles[j]
|
|
186
|
+
const dist = Math.hypot(particleA.posX - particleB.posX, particleA.posY - particleB.posY)
|
|
187
|
+
const angle = Math.atan2(particleB.posY - particleA.posY, particleB.posX - particleA.posX)
|
|
180
188
|
|
|
181
189
|
if (dist < this.options.particles.connectDist / 2) {
|
|
182
190
|
// Apply repulsive force on all particles close together
|
|
183
191
|
const grav = (1 / Math.max(dist, 10)) ** 1.8 * gravRepulsiveMult
|
|
184
192
|
const gravX = Math.cos(angle) * grav
|
|
185
193
|
const gravY = Math.sin(angle) * grav
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
194
|
+
particleA.velX -= gravX
|
|
195
|
+
particleA.velY -= gravY
|
|
196
|
+
particleB.velX += gravX
|
|
197
|
+
particleB.velY += gravY
|
|
190
198
|
} else if (enabledPulling) {
|
|
191
199
|
// Apply pulling force on all particles not close together
|
|
192
200
|
const grav = (1 / Math.max(dist, 10)) ** 1.8 * gravPullingMult
|
|
193
201
|
const gravX = Math.cos(angle) * grav
|
|
194
202
|
const gravY = Math.sin(angle) * grav
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
203
|
+
particleA.velX += gravX
|
|
204
|
+
particleA.velY += gravY
|
|
205
|
+
particleB.velX -= gravX
|
|
206
|
+
particleB.velY -= gravY
|
|
199
207
|
}
|
|
200
208
|
}
|
|
201
209
|
}
|
|
202
210
|
}
|
|
203
211
|
|
|
204
|
-
for (let
|
|
212
|
+
for (let particle of this.particles) {
|
|
205
213
|
// Moving the particle
|
|
206
|
-
|
|
207
|
-
(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
214
|
+
particle.dir =
|
|
215
|
+
(particle.dir + Math.random() * this.options.particles.rotationSpeed * 2 - this.options.particles.rotationSpeed) % (2 * Math.PI)
|
|
216
|
+
particle.velX *= this.options.gravity.friction
|
|
217
|
+
particle.velY *= this.options.gravity.friction
|
|
218
|
+
particle.posX = (particle.posX + particle.velX + ((Math.sin(particle.dir) * particle.speed) % this.width) + this.width) % this.width
|
|
219
|
+
particle.posY =
|
|
220
|
+
(particle.posY + particle.velY + ((Math.cos(particle.dir) * particle.speed) % this.height) + this.height) % this.height
|
|
212
221
|
|
|
213
|
-
const distX =
|
|
214
|
-
const distY =
|
|
222
|
+
const distX = particle.posX + this.offX - this.mouseX
|
|
223
|
+
const distY = particle.posY + this.offY - this.mouseY
|
|
215
224
|
|
|
216
225
|
// Mouse events
|
|
217
226
|
if (this.options.mouse.interactionType !== 0) {
|
|
218
227
|
const distRatio = this.options.mouse.connectDist / Math.hypot(distX, distY)
|
|
219
228
|
|
|
220
229
|
if (this.options.mouse.distRatio < distRatio) {
|
|
221
|
-
|
|
222
|
-
|
|
230
|
+
particle.offX += (distRatio * distX - distX - particle.offX) / 4
|
|
231
|
+
particle.offY += (distRatio * distY - distY - particle.offY) / 4
|
|
223
232
|
} else {
|
|
224
|
-
|
|
225
|
-
|
|
233
|
+
particle.offX -= particle.offX / 4
|
|
234
|
+
particle.offY -= particle.offY / 4
|
|
226
235
|
}
|
|
227
236
|
}
|
|
228
|
-
|
|
229
|
-
|
|
237
|
+
particle.x = particle.posX + particle.offX
|
|
238
|
+
particle.y = particle.posY + particle.offY
|
|
230
239
|
|
|
231
240
|
if (this.options.mouse.interactionType === 2) {
|
|
232
241
|
// Make the mouse actually move the particles
|
|
233
|
-
|
|
234
|
-
|
|
242
|
+
particle.posX = particle.x
|
|
243
|
+
particle.posY = particle.y
|
|
235
244
|
}
|
|
236
|
-
|
|
237
|
-
|
|
245
|
+
particle.x += this.offX
|
|
246
|
+
particle.y += this.offY
|
|
238
247
|
|
|
239
|
-
|
|
240
|
-
|
|
248
|
+
particle.gridPos = this.gridPos(particle)
|
|
249
|
+
particle.isVisible = particle.gridPos.x === 1 && particle.gridPos.y === 1
|
|
241
250
|
}
|
|
242
251
|
}
|
|
243
252
|
|
|
@@ -255,34 +264,34 @@ export default class CanvasParticles {
|
|
|
255
264
|
* - { x: 1, y: 2 } = bottom
|
|
256
265
|
* - { x: 2, y: 2 } = bottom-right
|
|
257
266
|
*
|
|
258
|
-
* @param {Object}
|
|
259
|
-
* @param {number}
|
|
260
|
-
* @param {number}
|
|
267
|
+
* @param {Object} particle - The coordinates of the particle.
|
|
268
|
+
* @param {number} particle.x - The x-coordinate of the particle.
|
|
269
|
+
* @param {number} particle.y - The y-coordinate of the particle.
|
|
261
270
|
* @returns {Object} - The calculated grid position of the particle.
|
|
262
271
|
* @returns {number} x - The horizontal grid position (0, 1, or 2).
|
|
263
272
|
* @returns {number} y - The vertical grid position (0, 1, or 2).
|
|
264
273
|
*/
|
|
265
|
-
gridPos = function (
|
|
274
|
+
gridPos = function (particle) {
|
|
266
275
|
return {
|
|
267
|
-
x: (
|
|
268
|
-
y: (
|
|
276
|
+
x: (particle.x >= particle.bounds.left) + (particle.x > particle.bounds.right),
|
|
277
|
+
y: (particle.y >= particle.bounds.top) + (particle.y > particle.bounds.bottom),
|
|
269
278
|
}
|
|
270
279
|
}
|
|
271
280
|
|
|
272
281
|
/**
|
|
273
282
|
* Determines whether a line between 2 particles crosses through the visible center of the canvas.
|
|
274
|
-
* @param {Object}
|
|
275
|
-
* @param {Object}
|
|
283
|
+
* @param {Object} particleA - First particle with {gridPos, isVisible}.
|
|
284
|
+
* @param {Object} particleB - Second particle with {gridPos, isVisible}.
|
|
276
285
|
* @returns {boolean} - True if the line crosses the visible center, false otherwise.
|
|
277
286
|
*/
|
|
278
|
-
isLineVisible = function (
|
|
279
|
-
// Visible if either
|
|
280
|
-
if (
|
|
287
|
+
isLineVisible = function (particleA, particleB) {
|
|
288
|
+
// Visible if either particle is in the center
|
|
289
|
+
if (particleA.isVisible || particleB.isVisible) return true
|
|
281
290
|
|
|
282
|
-
// Not visible if both
|
|
291
|
+
// Not visible if both particles are in the same vertical or horizontal line but outside the center
|
|
283
292
|
return !(
|
|
284
|
-
(
|
|
285
|
-
(
|
|
293
|
+
(particleA.gridPos.x === particleB.gridPos.x && particleA.gridPos.x !== 1) ||
|
|
294
|
+
(particleA.gridPos.y === particleB.gridPos.y && particleA.gridPos.y !== 1)
|
|
286
295
|
)
|
|
287
296
|
}
|
|
288
297
|
|
|
@@ -295,24 +304,24 @@ export default class CanvasParticles {
|
|
|
295
304
|
this.ctx.fillStyle = this.options.particles.color + this.options.particles.opacity.hex
|
|
296
305
|
this.ctx.lineWidth = 1
|
|
297
306
|
|
|
298
|
-
for (let
|
|
299
|
-
if (
|
|
307
|
+
for (let particle of this.particles) {
|
|
308
|
+
if (particle.isVisible) {
|
|
300
309
|
// Draw the particle as a square if the size is smaller than 1 pixel (±183% faster than drawing only circles)
|
|
301
|
-
if (
|
|
310
|
+
if (particle.size > 1) {
|
|
302
311
|
// Draw circle
|
|
303
312
|
this.ctx.beginPath()
|
|
304
|
-
this.ctx.arc(
|
|
313
|
+
this.ctx.arc(particle.x, particle.y, particle.size, 0, 2 * Math.PI)
|
|
305
314
|
this.ctx.fill()
|
|
306
315
|
this.ctx.closePath()
|
|
307
316
|
} else {
|
|
308
317
|
// Draw square (±335% faster than circle)
|
|
309
|
-
this.ctx.fillRect(
|
|
318
|
+
this.ctx.fillRect(particle.x - particle.size, particle.y - particle.size, particle.size * 2, particle.size * 2)
|
|
310
319
|
}
|
|
311
320
|
}
|
|
312
321
|
}
|
|
313
322
|
|
|
314
323
|
const len = this.len
|
|
315
|
-
const drawAll = this.options.particles.connectDist >= Math.min(this.width, this.height)
|
|
324
|
+
const drawAll = this.options.particles.connectDist >= Math.min(this.canvas.width, this.canvas.height)
|
|
316
325
|
|
|
317
326
|
const maxWorkPerParticle = this.options.particles.connectDist * this.options.particles.maxWork
|
|
318
327
|
const maxWork = maxWorkPerParticle * len
|
|
@@ -323,16 +332,16 @@ export default class CanvasParticles {
|
|
|
323
332
|
|
|
324
333
|
for (let j = i + 1; j < len; j++) {
|
|
325
334
|
// Code in this scope runs [particles ** 2 / 2] times!
|
|
326
|
-
const
|
|
327
|
-
const
|
|
335
|
+
const particleA = this.particles[i]
|
|
336
|
+
const particleB = this.particles[j]
|
|
328
337
|
|
|
329
338
|
// Draw a line if its visible
|
|
330
|
-
if (this.isLineVisible(
|
|
331
|
-
const distX =
|
|
332
|
-
const distY =
|
|
339
|
+
if (this.isLineVisible(particleA, particleB) | drawAll) {
|
|
340
|
+
const distX = particleA.x - particleB.x
|
|
341
|
+
const distY = particleA.y - particleB.y
|
|
333
342
|
const dist = Math.sqrt(distX * distX + distY * distY)
|
|
334
343
|
|
|
335
|
-
// Connect the 2
|
|
344
|
+
// Connect the 2 particles with a line if the distance is small enough
|
|
336
345
|
if (dist < this.options.particles.connectDist) {
|
|
337
346
|
// Calculate the transparency of the line
|
|
338
347
|
if (dist >= this.options.particles.connectDist / 2) {
|
|
@@ -344,8 +353,8 @@ export default class CanvasParticles {
|
|
|
344
353
|
|
|
345
354
|
// Draw the line
|
|
346
355
|
this.ctx.beginPath()
|
|
347
|
-
this.ctx.moveTo(
|
|
348
|
-
this.ctx.lineTo(
|
|
356
|
+
this.ctx.moveTo(particleA.x, particleA.y)
|
|
357
|
+
this.ctx.lineTo(particleB.x, particleB.y)
|
|
349
358
|
this.ctx.stroke()
|
|
350
359
|
|
|
351
360
|
if ((work += dist) >= maxWork || (particleWork += dist) >= maxWorkPerParticle) break
|
|
@@ -407,6 +416,7 @@ export default class CanvasParticles {
|
|
|
407
416
|
} else {
|
|
408
417
|
// Example: extract 0.25 from rgba(136, 244, 255, 0.25) and convert to range 0x00 to 0xff and store as a 2 char string
|
|
409
418
|
const value = ~~(this.ctx.fillStyle.split(',').at(-1).slice(1, -1) * 255)
|
|
419
|
+
|
|
410
420
|
this.options.particles.opacity = {
|
|
411
421
|
value: value,
|
|
412
422
|
hex: value.toString(16),
|
package/package.json
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "canvasparticles-js",
|
|
3
|
-
"version": "3.2.
|
|
4
|
-
"description": "In an HTML canvas, a bunch of floating particles connected with lines when they approach eachother. Creating a fun and interactive background.",
|
|
5
|
-
"main": "canvasParticles.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/Khoeckman/canvasParticles.git"
|
|
10
|
-
},
|
|
11
|
-
"keywords": [
|
|
12
|
-
"front-end",
|
|
13
|
-
"frontend",
|
|
14
|
-
"canvas",
|
|
15
|
-
"particles",
|
|
16
|
-
"particle",
|
|
17
|
-
"animation",
|
|
18
|
-
"animated",
|
|
19
|
-
"javascript",
|
|
20
|
-
"js",
|
|
21
|
-
"html5",
|
|
22
|
-
"html"
|
|
23
|
-
],
|
|
24
|
-
"author": "Kyle Hoeckman",
|
|
25
|
-
"license": "MIT",
|
|
26
|
-
"bugs": {
|
|
27
|
-
"url": "https://github.com/Khoeckman/canvasParticles/issues"
|
|
28
|
-
},
|
|
29
|
-
"homepage": "http://kylehoeckman.great-site.net/canvas-particles/"
|
|
30
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "canvasparticles-js",
|
|
3
|
+
"version": "3.2.14",
|
|
4
|
+
"description": "In an HTML canvas, a bunch of floating particles connected with lines when they approach eachother. Creating a fun and interactive background.",
|
|
5
|
+
"main": "canvasParticles.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Khoeckman/canvasParticles.git"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"front-end",
|
|
13
|
+
"frontend",
|
|
14
|
+
"canvas",
|
|
15
|
+
"particles",
|
|
16
|
+
"particle",
|
|
17
|
+
"animation",
|
|
18
|
+
"animated",
|
|
19
|
+
"javascript",
|
|
20
|
+
"js",
|
|
21
|
+
"html5",
|
|
22
|
+
"html"
|
|
23
|
+
],
|
|
24
|
+
"author": "Kyle Hoeckman",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/Khoeckman/canvasParticles/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "http://kylehoeckman.great-site.net/canvas-particles/"
|
|
30
|
+
}
|