
A great alternative to tsParticles and Particle.js.
perParticles.js is a blazing fast (high FPS) particle library for effectively handling a larger amount of particles on the screen.
How to use it:
1. Insert the perParticles.css and perParticles.js into the document.
<link rel="stylesheet" href="perParticles.css" /> <script src="perParticles.js"></script>
2. Create an HTML canvas element for the particle system.
<canvas></canvas>
3. Generate particles on the canvas.
// updateDaemon.js
const createNode = options => {
const {
minNodeSize,
maxNodeSize,
minVelocity,
maxVelocity,
width,
height
} = options;
const nodeX = Math.floor(Math.random() * (width + 100) - 50);
const nodeY = Math.floor(Math.random() * (height + 100) - 50);
const nodeVelocityX = (Math.random() * maxVelocity + minVelocity) * (Math.round(Math.random()) ? 1 : -1);
const nodeVelocityY = (Math.random() * maxVelocity + minVelocity) * (Math.round(Math.random()) ? 1 : -1);
const nodeRadius = Math.floor(Math.random() * maxNodeSize + minNodeSize);
return { x: nodeX, y: nodeY, r: nodeRadius, vx: nodeVelocityX, vy: nodeVelocityY };
};
self.addEventListener('message', e => {
const { command, nodes, options } = e.data;
switch (command) {
case 'update':
const { nodesAmount, maxVelocity, minVelocity, width, height } = options;
while (nodes.length < nodesAmount) {
nodes.push(createNode(options));
}
if (nodes.length > nodesAmount) {
nodes.length = nodesAmount;
}
for (let i = 0; i < nodes.length; i++) {
nodes[i].x += nodes[i].vx;
nodes[i].y += nodes[i].vy;
if ((nodes[i].x < -25 || nodes[i].x > width + 25) || (nodes[i].y < -25 || nodes[i].y > height + 25)) {
nodes[i].vx = (Math.random() * maxVelocity + minVelocity) * (nodes[i].vx < 0 ? 1 : -1);
nodes[i].vy = (Math.random() * maxVelocity + minVelocity) * (nodes[i].vy < 0 ? 1 : -1);
}
}
const buckets = [];
const numberOfBuckets = 5;
const bucketWidth = Math.ceil(width / numberOfBuckets);
for (let i = 0; i < numberOfBuckets; i++) {
buckets.push({ x: i * bucketWidth - 50, y: -25, w: bucketWidth + 100, h: height + 50, nodes: [] });
}
nodes.forEach((node) => {
buckets.forEach((bucket) => {
if (node.x >= bucket.x && node.x <= bucket.x + bucket.w && node.y >= bucket.y && node.y <= bucket.y + bucket.h) {
bucket.nodes.push(node);
}
});
});
self.postMessage({ nodes, buckets });
break;
case 'stop':
self.close();
break;
};
});
// bucketDaemon.js
const getDistance = (node1, node2) => {
const distanceX = Math.abs(node1.x - node2.x);
const distanceY = Math.abs(node1.y - node2.y);
return Math.sqrt(distanceX ** 2 + distanceY ** 2);
};
self.addEventListener('message', e => {
const { command, bucket } = e.data;
switch (command) {
case 'process':
const lines = [];
bucket.nodes.forEach((node, i) => {
bucket.nodes.slice(i + 1).forEach(n => {
const distance = getDistance(node, n);
if (distance < 150) {
lines.push({ n1: node, n2: n, distance });
}
});
});
self.postMessage({ lines });
break;
case 'stop':
self.close();
break;
};
});
4. Customize the particles by overriding the parameters at the beginning of the perParticles.js
let minNodeSize = 1; let maxNodeSize = 3; let minVelocity = 0.25; let maxVelocity = 2; let nodesAmount = 1000; let backgroundColor = '#222222'; let nodeColor = '#D1C4E9'; let lineColor = '#CE93D8';







