Snowfall in JavaScript

This single-file snowfall effect uses HTML Canvas and JavaScript to create a smooth, lightweight animation of falling snowflakes across the screen. The canvas automatically resizes to fit the browser window, while each snowflake is randomly generated with its own size, speed, and horizontal drift to simulate natural movement. The animation runs efficiently using requestAnimationFrame, continuously clearing and redrawing the scene to give the illusion of gentle snowfall. Because all HTML, CSS, and JavaScript are contained in one file, it is easy to use, customize, and deploy without any external dependencies.

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Set character encoding -->
  <meta charset="UTF-8" />

  <!-- Page title -->
  <title>Snowfall Effect</title>

  <style>
    /* Remove default spacing and make page full height */
    html, body {
      margin: 0;              /* Remove default margin */
      padding: 0;             /* Remove default padding */
      background: #0b1d3a;    /* Dark blue background (night sky) */
      overflow: hidden;       /* Prevent scrollbars */
      height: 100%;           /* Full viewport height */
    }

    /* Make canvas fill the screen */
    canvas {
      display: block;         /* Remove inline spacing */
    }
  </style>
</head>
<body>

  <!-- Canvas where snow will be drawn -->
  <canvas id="snow"></canvas>

  <script>
    // Get the canvas element by its ID
    const canvas = document.getElementById("snow");

    // Get 2D drawing context from canvas
    const ctx = canvas.getContext("2d");

    // Function to resize canvas to window size
    function resize() {
      canvas.width = window.innerWidth;   // Match window width
      canvas.height = window.innerHeight; // Match window height
    }

    // Initial resize when page loads
    resize();

    // Resize canvas whenever window size changes
    window.addEventListener("resize", resize);

    // Array to store all snowflake objects
    const snowflakes = [];

    // Total number of snowflakes
    const SNOW_COUNT = 200;

    // Create snowflake objects
    for (let i = 0; i < SNOW_COUNT; i++) {
      snowflakes.push({
        x: Math.random() * canvas.width,  // Random horizontal position
        y: Math.random() * canvas.height, // Random vertical position
        r: Math.random() * 3 + 1,          // Radius (size) of snowflake
        speed: Math.random() * 2 + 0.5,    // Falling speed
        drift: Math.random() * 0.6 - 0.3   // Horizontal movement (wind)
      });
    }

    // Main drawing function
    function draw() {
      // Clear entire canvas before redrawing
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Set snowflake color
      ctx.fillStyle = "white";

      // Start a new drawing path
      ctx.beginPath();

      // Draw each snowflake
      for (const s of snowflakes) {
        ctx.moveTo(s.x, s.y);                 // Move drawing cursor
        ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2); // Draw circular snowflake
      }

      // Fill all snowflakes with color
      ctx.fill();

      // Update snowflake positions
      update();

      // Request next animation frame (smooth animation)
      requestAnimationFrame(draw);
    }

    // Update snowflake movement
    function update() {
      for (const s of snowflakes) {
        s.y += s.speed;   // Move snowflake downward
        s.x += s.drift;   // Move snowflake sideways (wind)

        // If snowflake falls below screen, reset to top
        if (s.y > canvas.height) {
          s.y = -s.r;                         // Start above canvas
          s.x = Math.random() * canvas.width; // Random horizontal position
        }

        // Wrap snowflake horizontally
        if (s.x > canvas.width) s.x = 0;
        if (s.x < 0) s.x = canvas.width;
      }
    }

    // Start the animation loop
    draw();
  </script>

</body>
</html>

Leave a Reply

Your email address will not be published. Required fields are marked *