JS: Falling Snow Effect

By Xah Lee. Date: . Last updated: .
JavaScript raining hearts
JavaScript falling image effect.

This page shows you how to use JavaScript to create a “raining hearts” or “falling snow” effect.

Here's the JavaScript code:

// 2014-08-18
// 2017-08-13
// copyright 2014 Xah Lee
// feel free to use, but must give credit, link back to this page
// from http://xahlee.info/js/js_raining_hearts.html

{

    const num_of_hearts = 20;
    const driftX = 2; // each frame, drift left/right this much
    const driftY = 8;
    const update_speed = 100; // millisecond

    const heartTypes=["♥","💕","💓","💔","💖","💗","💘","💝","💞","💟","💙","💚","💛","💜",
                      "✨","❇","❈","❄","❅","❆","✿","❀","❁","✾",
                      "★","☆","⚝","✩","✫","✬","✭","✮","✯","✰"
                     ];

    const viewportWidth = document.documentElement.clientWidth;
    const viewportHeight = document.documentElement.clientHeight;

    const viewSpaceWidth = viewportWidth+50;
    const viewSpaceHeight = viewportHeight+50;

    const randomInt = ((xmin,xmax) => (Math.floor( Math.random() * (xmax + 1 - xmin) + xmin )));

    const randomReal = ((xmin,xmax) => ( Math.random() * (xmax - xmin) + xmin ));

    const randomColor = (() => ("hsla" + "(" + randomInt(0,360) + "," +
            randomInt(70,100) + "%," +
            randomInt(40,60) + "%," +
            randomReal(.8,1) + ")" ) );

    const restartHeart = ((el) => {
        el.innerHTML= heartTypes[Math.floor( Math.random() * heartTypes.length )];
        el.posX=randomInt(0, viewSpaceWidth);
        el.posY=randomInt(0, viewSpaceHeight)-viewSpaceHeight;
        el.size= 10 + randomInt(0,30);
        el.rotate = randomInt(-1,1);
        el.style.color = randomColor();
        el.style.left= el.posX + "px";
        el.style.top= el.posY + "px";
        el.style.fontSize = el.size + "px";
        el.style.transform = "rotate(" + el.rotate + "deg)";
    });

    const heart_box = document.createElement("div");
    heart_box.setAttribute("id","heart_box");

    { // create Hearts
        const hearts = new Array(num_of_hearts);
        for (let i=0; i < hearts.length; i++) {
            const el = document.createElement("div");
            restartHeart(el);
            el.style.position="fixed";
            el.style.zIndex= (i+100) .toString ();
            heart_box.appendChild(el);
        } } ;

    document.body.appendChild(heart_box);

    const heartNodes = document.getElementById("heart_box").childNodes;

    const update_positions = (() => {

        for (let i = 0; i < heartNodes.length; i++) {
            const thisHeart = heartNodes[i];

            thisHeart.posX += 
            (() => {
                const rnd = Math.random();
                if ( rnd < 0.3333 ) {
                    return 0;
                } else if ( rnd < 0.6666) {
                    return driftX;}
                else {
                    return - driftX;
                }
            }) ();

            thisHeart.posY = thisHeart.posY + ( (thisHeart.size/20) * (driftY) );

            if ( thisHeart.posY > viewSpaceHeight ) {
                restartHeart(thisHeart);
            } else {
                thisHeart.posY = thisHeart.posY % viewSpaceHeight; };

            if ( thisHeart.rotate !== 0 ) {
                thisHeart.rotate = thisHeart.rotate + randomInt(-30,30);
                thisHeart.style.transform = "rotate(" + thisHeart.rotate + "deg)";
            };

            thisHeart.style.left = thisHeart.posX + "px";
            thisHeart.style.top= thisHeart.posY + "px";
        }
    });

    setInterval( update_positions , update_speed);
}
;

How Does it Work?

The main thing is to create HTML elements with CSS that's fixed position with respect to window. Each element is a “heart” in its own layer. Then, just create a loop to update the element's positions.

Simple DOM Examples

  1. JS: Change CSS
  2. DOM: Change Element's Content
  3. DOM: Create HTML Element
  4. DOM: Remove HTML Element

  1. JS: document.write
  2. JS: Image Rollover
  3. JS: Pop-up New Window
  4. JS: Digital Clock
  5. JS: Stopwatch
  6. JS: Fade a Element
  7. JS: Fade a Element Using CSS Transition
  8. JavaScript UI: Shake Element
  9. JS: How to Create Tooltip
  10. JS: Falling Snow Effect
  11. JavaScript Floating Box Following Scroll
Liket it? Put $5 at patreon.

Or, Buy JavaScript in Depth

Ask me question on patreon