This is another Florin Pop mini project where he makes 10 JS projects in 1 hour.
I added the start and stop buttons which was a bit more involved than the original.
Here is the code without the stop/start buttons. (You can see the full code embedded in the page at the bottom.)
function createHeart() {
const heart = document.createElement('div');
heart.classList.add('heart');
heart.style.left = Math.random() * 100 + 'vw';
heart.style.animationDuration = Math.random() * 3 + 5 + 's';
heart.innerText = '💜';
document.body.appendChild(heart);
// setTimeout(heart.remove(), 4000);
setTimeout(() => heart.remove(), 8000);
}
How it works
This relies on a bit of CSS, including animation and in fact it’s possible to create more or less the same effect with only CSS.
.heart {
position: fixed;
top: -4vh;
left: 50vw;
animation: fall 4s linear;
}
@keyframes fall {
to {
transform: translateY(104vh);
}
}
The last line, the setInterval
function, is where things start. This is only needs to be stored in a variable if you want a stop button, otherwise just use setInterval(createHeart, 200);
.
(It’s worth noting that although it looks like a simple variable declaration the function will still start after the initial number of milliseconds.)
This built in function takes two parameters: first the name of function to run and second the interval between each run of the function in millisectonds. So the createHeart
function is run every 200 milliseconds or 0.2 seconds. So what does it do?
The first two lines create a new <div>
and adds the class of heart
to it.
Next an inline style is added to the <div>
. In the CSS the position
is set to fixed
so this left
property defines how far from the left side of the viewport it is. The hearts need to be randomly placed at the top of the viewport, just out of sight. This is done in the CSS with
.heart {
position: fixed;
top: -4vh;
}
However for the left
setting JavaScript’s built in random number generator is used to generate a different position for each heart <div>
.
heart.style.left = Math.random() * 100 + 'vw';
Since JavaScript random numbers are between 0 and 1 this number is multiplied by 100 so that the numbers are between 0 and 100 which is the full width of the screen in viewport width units. (1vw
= 1% of the viewport width).
Next the purple heart is added using an emoji. The code for purple heart emoji is :purple_heart
:. You could also post the symbol directly into the code too 💜 if you prefer.
So far the createHeart
function has created a new <div>
, added a heart emoji to it and added an inline style to position it a random distance from the left. But whereabouts in the document should it be? Well at the moment it’s nowhere so for it to exist it needs to be told where to go. The next line does that, it appends this new <div>
as the child element of any element we choose. In this case it’s the <body>
element which can be added directly after document
document.body.appendChild(heart);
The word heart
above refers to the variable name declared at the start of the function so it’s not enclosed with quotes.
So far the function is churning out new purple heart divs at a rate of 5 per second. A CSS animation makes them fall from the top of the screen to the bottom but after that they will just mount up just out of view below the bottom of the viewport. In a few minutes there will be hundreds of these so we need to get rid of them.
So a finally the built in setTimeout
method is used to remove the <div>
after 8 seconds. This is written as an arrow function which is more succinct:
setTimeout(() => heart.remove(), 8000);
setTimeout(() => {
heart.remove();
}, 8000);