<canvas id="rain-effect"></canvas>
body {
margin: 0;
width: 100vw;
height: 100vh;
}
#rain-effect {
display: block;
width: 100%;
height: 100%;
}
class RainChar {
constructor(font, charSize, chars, bg, fg) {
// Defining the parameters
this.font = font;
this.charSize = charSize;
this.chars = chars;
this.bg = bg;
this.fg = fg;
// Setting up the canvas
const canvas = document.getElementById("rain-effect");
this.context = canvas.getContext("2d");
this.size = [canvas.offsetWidth, canvas.offsetHeight];
canvas.width = this.size[0];
canvas.height = this.size[1];
this.context.fillStyle = this.bg;
this.context.fillRect(0, 0, ...this.size);
// Creating the particles array
this.particles = [];
const particleCount =
(this.size[0] * this.size[1]) / this.charSize ** 2 / 10;
for (let i = 0; i < particleCount; i++) {
this.particles.push(this.newParticle());
}
}
newParticle() {
return {
x: Math.random() * this.size[0],
y: -Math.random() * this.size[1] * 2,
size: Math.floor(
Math.random() * (this.charSize * 2 - this.charSize / 2) +
this.charSize / 2
)
};
}
drawParticles() {
this.context.fillStyle = this.fg;
this.particles.forEach((particle) => {
this.context.font = `${particle.size}px ${this.font}`;
const randomChar = this.chars[
Math.floor(Math.random() * this.chars.length)
];
this.context.fillText(randomChar, particle.x, particle.y);
});
}
updateParticles() {
this.particles.forEach((particle) => {
if (particle.y > this.size[1]) {
Object.assign(particle, this.newParticle());
} else {
particle.y += particle.size;
}
});
}
clearCanvas() {
this.context.globalAlpha = 0.25;
this.context.fillStyle = this.bg;
this.context.fillRect(0, 0, ...this.size);
this.context.globalAlpha = 1;
}
play() {
this.clearCanvas();
this.drawParticles();
this.updateParticles();
setTimeout(() => {
this.play();
}, 50);
}
}
const chars = "ABCDEFGHIJKLMNOPRSTUVWXYZ";
const rain = new RainChar("monospace", 20, chars, "black", "lime");
rain.play();
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.