Happy Holidays - Snowfall (2024)
<!DOCTYPE html><html lang="en"><!-- original-source: https://codepen.io/ethancopping/pen/ExrGYGG --><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Happy Holidays</title>    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"        integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg=="        crossorigin="anonymous" referrerpolicy="no-referrer" />
    <style>        body,        html {            margin: 0;            padding: 0;            background-color: rgba(20, 20, 25, 1);        }
        body,        html {            overflow-x: hidden;            width: 100vw;            height: auto;        }
        .snow-container {            position: fixed;            top: 0;            left: 0;            overflow: hidden;            width: 100vw;            height: 100vh;            z-index: 99999;            pointer-events: none;        }
        .snowflake {            position: absolute;            background-color: white;            border-radius: 50%;            opacity: 0.8;            pointer-events: none;        }
        @keyframes fall {            0% {                opacity: 0;                transform: translateY(0);            }
            10% {                opacity: 1;            }
            100% {                opacity: 0.5;                transform: translateY(100vh);            }        }
        @keyframes diagonal-fall {            0% {                opacity: 0;                transform: translate(0, 0);            }
            10% {                opacity: 1;            }
            100% {                opacity: 0.25;                transform: translate(10vw, 100vh);            }        }
        .author {            position: absolute;            top: 40%;            right: 20%;            color: white;            font-size: 2rem;            font-family: Arial, Helvetica, sans-serif;            text-align: center;        }    </style></head>
<body>    <div class="snow-container"></div>    <div style="height: 200vh;" />
    <div class="author">        <div style="font-size: 3rem; margin-bottom: 20px;">Happy Holidays</div>        <i class="fa-brands fa-youtube fa-2xl" style="color: #ff0000;"></i>        /@SanthoshBalajiRamesh    </div>
    <script>        document.addEventListener("DOMContentLoaded", function () {            const snowContainer = document.querySelector(".snow-container");
            const particlesPerThousandPixels = 0.1;            const fallSpeed = 1.25;            const pauseWhenNotActive = true;            const maxSnowflakes = 200;            const snowflakes = [];
            let snowflakeInterval;            let isTabActive = true;
            function resetSnowflake(snowflake) {                const size = Math.random() * 5 + 1;                const viewportWidth = window.innerWidth - size; // Adjust for snowflake size                const viewportHeight = window.innerHeight;
                snowflake.style.width = `${size}px`;                snowflake.style.height = `${size}px`;                snowflake.style.left = `${Math.random() * viewportWidth}px`; // Constrain within viewport width                snowflake.style.top = `-${size}px`;
                const animationDuration = (Math.random() * 3 + 2) / fallSpeed;                snowflake.style.animationDuration = `${animationDuration}s`;                snowflake.style.animationTimingFunction = "linear";                snowflake.style.animationName =                    Math.random() < 0.5 ? "fall" : "diagonal-fall";
                setTimeout(() => {                    if (parseInt(snowflake.style.top, 10) < viewportHeight) {                        resetSnowflake(snowflake);                    } else {                        snowflake.remove(); // Remove when it goes off the bottom edge                    }                }, animationDuration * 1000);            }
            function createSnowflake() {                if (snowflakes.length < maxSnowflakes) {                    const snowflake = document.createElement("div");                    snowflake.classList.add("snowflake");                    snowflakes.push(snowflake);                    snowContainer.appendChild(snowflake);                    resetSnowflake(snowflake);                }            }
            function generateSnowflakes() {                const numberOfParticles =                    Math.ceil((window.innerWidth * window.innerHeight) / 1000) *                    particlesPerThousandPixels;                const interval = 5000 / numberOfParticles;
                clearInterval(snowflakeInterval);                snowflakeInterval = setInterval(() => {                    if (isTabActive && snowflakes.length < maxSnowflakes) {                        requestAnimationFrame(createSnowflake);                    }                }, interval);            }
            function handleVisibilityChange() {                if (!pauseWhenNotActive) return;
                isTabActive = !document.hidden;                if (isTabActive) {                    generateSnowflakes();                } else {                    clearInterval(snowflakeInterval);                }            }
            generateSnowflakes();
            window.addEventListener("resize", () => {                clearInterval(snowflakeInterval);                setTimeout(generateSnowflakes, 1000);            });
            document.addEventListener("visibilitychange", handleVisibilityChange);        });
    </script></body>
</html>