I would like to add a particle system to a page that generates an appropriate number of particles based on the size of the screen. These particles must never fall outside the screen, but float over the current page.
Unfortunately, I have not been able to generate a nice transition of the particles, which is why I am now looking for help here. At the moment, a new position is simply calculated based on the current position by adjusting the coordinates by the size of the particle.
However, as I do this at a fixed interval, the entire system seems very robotic and not very nice, as the particles virtually teleport back and forth.
I have therefore tried to build the whole thing as HTML and thus tried to incorporate a few transitions with CSS, but that didn't help much either.
How do I set up my code so that the particles use a random image I have predefined and preferably don't need any HTML code but still fly nicely through the entire screen with different directions and generate a suitable number of particles based on the screen size?
I don't want a direction to be predefined and just bounce off the screen.
(() => {
const SIZE = 10;
const COUNT = 15;
let PARTICLES = [];
let INTERVAL = null;
const particles = document.getElementById('particles');
if (!particles) return;
const handleGeneration = _ => {
for (let i = 0; i < COUNT; i++) {
const particle = document.createElement('span');
particle.style.top = Math.floor(Math.random() * window.innerHeight) + 'px';
particle.style.left = Math.floor(Math.random() * window.innerWidth) + 'px';
particles.appendChild(particle);
PARTICLES.push(particle);
}
};
const handleMovement = _ => {
const parseRandom = _ => {
const random = Math.floor(Math.random() * 3);
switch (random) {
case 1:
return SIZE;
case 2:
return -SIZE;
default:
return random;
}
};
INTERVAL = setInterval(_ => {
PARTICLES.forEach((particle, index) => {
let top = parseInt(particle.style.top);
let left = parseInt(particle.style.left);
let directionTop = parseRandom();
let directionLeft = parseRandom();
if (top + directionTop < 0)
directionTop = SIZE;
else if (top + directionTop >= window.innerWidth - SIZE)
directionTop = -SIZE;
if (left + directionLeft < 0)
directionLeft = SIZE;
else if (left + directionLeft >= window.innerWidth - SIZE)
directionLeft = -SIZE;
particle.style.top = top + directionTop + 'px';
particle.style.left = left + directionLeft + 'px';
});
}, 125);
};
const handleResize = _ => {
window.addEventListener('resize', _ => {
PARTICLES.forEach(particle => particle.remove());
PARTICLES = [];
clearInterval(INTERVAL);
handleGeneration();
handleMovement();
});
window.dispatchEvent(new Event('resize'));
};
handleResize();
})();
#particles {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
opacity: .25;
}
#particles span {
position: absolute;
height: 10px;
width: 10px;
/* mask-repeat: no-repeat; */
/* mask-size: contain; */
/* mask-position: center; */
/* mask-image: url('../../Icons/square.svg'); */
transition: top 250ms linear, left 250ms linear;
}
#particles span:nth-child(odd) {
background-color: blue;
}
#particles span:nth-child(even) {
background-color: red;
}
<div id="particles"></div>
I find it best to use Math.sin() or Math.cos() to make objects move smoothly.
let amount = window.innerWidth * window.innerHeight / 5000;
let myarray = [];
let randomization = 5, k1, k2;
for(i = 0; i < amount; i ++){
let square = document.createElement("div");
square.id = "id" + i;
square.style.width = square.style.height = "10px";
square.style.position = "absolute";
square.style.background = "rgb(" + Math.floor(256 * Math.random()) + ", " + Math.floor(256 * Math.random()) + ", " + Math.floor(256 * Math.random()) + ")";
document.body.append(square);
for(j = 0; j < randomization; j ++){
myarray.push(Math.random());
myarray.push(Math.random());
}
}
let x, y;
let t = 10000;
setInterval(function(){
for(i = 0; i < amount; i ++){
k1 = k2 = 0;
for(j = 0; j < randomization; j ++){
k1 += Math.sin(t / (100 + 200 * myarray[(i * randomization + j) * 2]));
k2 += Math.sin(t / (100 + 200 * myarray[(i * randomization + j) * 2 + 1]));
}
x = window.innerWidth / 2 + window.innerWidth / 2 / randomization * k1;
y = window.innerHeight / 2 + window.innerHeight / 2 / randomization * k2;
document.getElementById("id" + i).style.left = x + "px";
document.getElementById("id" + i).style.top = y + "px";
}
t ++;
}, 20);