In this article, we are going to build a container that generates rain by using JS. And it is a colorful rain with random colors. You can play with colors however you want. So first, let's see what are we building.
Preview
Now let's look at the code, how we can make that work.
HTML
<div class="rain-container"></div>
CSS
* {
margin: 0;
padding: 0;
}
.rain-container {
position: relative;
background: #000;
width: 100vw;
height: 100vh;
overflow: hidden;
}
i {
position: absolute;
height: 120px;
border-radius: 0 0 999px 999px;
animation: animate 5s linear infinite;
}
@keyframes animate {
0% {
transform: translateY(-120px);
}
100% {
transform: translateY(calc(100vh + 120px));
}
}
Javascript
const rainContainer = document.querySelector(".rain-container");
// background Colors for the raindrop
const background = [
"linear-gradient(transparent, aqua)",
"linear-gradient(transparent, red)",
"linear-gradient(transparent, limegreen)",
"linear-gradient(transparent, white)",
"linear-gradient(transparent, yellow)"
];
const amount = 100; // amount of raindops
let i = 0;
// Looping and creating the raindrop then adding to the rainContainer
while (i < amount) {
// Creating and Element
const drop = document.createElement("i");
// CSS Properties for raindrop
const raindropProperties = {
width: Math.random() * 5 + "px",
positionX: Math.floor(Math.random() * window.innerWidth) + "px",
delay: Math.random() * -20 + "s",
duration: Math.random() * 5 + "s",
bg: background[Math.floor(Math.random() * background.length)],
opacity: Math.random() + 0.2
};
// Setting Styles for raindrop
drop.style.width = raindropProperties.width;
drop.style.left = raindropProperties.positionX;
drop.style.animationDelay = raindropProperties.delay;
drop.style.animationDuration = raindropProperties.duration;
drop.style.background = raindropProperties.bg;
drop.style.opacity = raindropProperties.opacity;
// Appending the raindrop in the raindrop container
rainContainer.appendChild(drop);
i++;
}
Wrapping Up
This is it. You can simply do that with this and you can also take this to the next level. If you enjoyed this article then don't forget to press ❤️. If you have any queries or suggestions don't hesitate to drop them. See you.
Top comments (11)
Why the "object for nothing" and all the manual assignments. Also "while" is slower than for, and if you leverage loose typecasting a decrement could be more optimal for such a loop. It's also not a great idea to CONST inside a loop since the point of CONST is it can't be re-assigned OR deleted (which is how it knows it's not reassigned). As such you're creating a bunch of instances that aren't removed from memory.
REALLY cute trick? appendChild returns the object appended. and if you use Object.assign on your created element.style, you can greatly reduce the code complexity.
Likewise if you use % for the left offset, it eliminates the bug of it showing single column if the script runs before the render is complete, and means you don't need to read clientWidth.
See this pen I forked off.
codepen.io/jason-knight/pen/vYeZKXG
A lot less code and far simpler too.
Actually that's nice, thanks for tips.
I played with it a bit further for fun, swapping a number of the parameters that were individually randomized to be uniform, since distance of the drop would impact apparent brightness (opacity) and size.
codepen.io/jason-knight/pen/xxXrgyG
Looks good, nice code reduction, good concise syntax ... reminds me of this:
Well done, Sir 👍
thanks a lot , very informative
It's my pleasure :)
Neat! 👍
Nice effect. I don't recommend bumping your count to 1,000,000. My browser did NOT like it.
LoL 😂
Maybe YOU can create a new post with better more optimized example!?
But as you can see we are generating random style for every element so we need to use JS.