console
let ctx = canvas.getContext('2d'),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
particles = [];
let settings = {
speed: 1,
lifeTime: 1000,
maxParticles: 50,
lineLength: 35,
radius: 0.6
};
function rotate(vec, angle) {
angle = angle * Math.PI / 180;
return [(vec[0] * Math.cos(angle)) - (vec[1] * Math.sin(angle)), (vec[0] * Math.sin(angle)) + (vec[1] * Math.cos(angle))];
}
let dirVecs = [
[1, 0],
rotate([1, 0], 120),
rotate([1, 0], 240)
];
function particle() {
this.x = 0;
this.y = 0;
this.age = 0;
this.dir = dirVecs[Math.floor(Math.random() * 3)];
this.color = 'hsl(' + ((Date.now() / 240.0) % 360.0) + ', 90%, light%)';
}
particle.prototype.updateAndDraw = function() {
this.age++;
if (this.age % settings.lineLength === 0) {
let dir1 = rotate(this.dir, 60);
let dir2 = rotate(this.dir, -60);
let options = [];
options = [dir1, dir2];
this.dir = options[Math.floor(Math.random() * options.length)];
}
ctx.fillStyle = this.color.replace('light', '40');
ctx.beginPath();
ctx.arc(width / 2.0 + this.x, height / 2.0 + this.y, settings.radius, 0, 6.3);
ctx.shadowBlur = settings.radius * 6;
ctx.shadowColor = this.color.replace('light', '40');
ctx.fill();
this.x += this.dir[0] * settings.speed;
this.y += this.dir[1] * settings.speed;
};
function updateAndDraw() {
ctx.shadowBlur = 0;
ctx.globalCompositeOperation = 'source-over';
ctx.fillStyle = 'rgb(0, 0, 0, 0.03)';
ctx.fillRect(0, 0, width, height);
ctx.globalCompositeOperation = 'lighter';
for (let i = particles.length - 1; i >= 0; i--) {
particles[i].updateAndDraw();
if (particles[i].age > settings.lifeTime) {
particles.splice(i, 1);
}
}
if (particles.length < settings.maxParticles) {
if (Math.random() > 0.9) {
particles.push(new particle());
}
} else if (particles.length > settings.maxParticles) {
particles.splice(0, settings.maxParticles);
}
requestAnimationFrame(updateAndDraw);
}
function onResize() {
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight;
ctx.fillStyle = '#111';
ctx.fillRect(0, 0, width, height);
}
function init() {
ctx.fillStyle = '#111';
ctx.fillRect(0, 0, width, height);
window.onresize = onResize;
updateAndDraw();
}
init();
<canvas id="canvas"></canvas>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
box-sizing: border-box;
}
#canvas {
display: block;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
}