The Falling Snow Effect

Does your browser’s developer tools console show any error? If you aren’t familiar with the console, this will help: https://www.kirupa.com/html5/console.htm :slight_smile:

Thanks for the great tutorial on snowflakes! I love the depth of your explanation… not many people go through the trouble… you’re the bomb!
-g.

1 Like

Help plz. I’ve got like 25 cm of snow now and I don’t know how to make it stop. I tried stop(); but it didn’t work. Please tell me how to stop falling snow effect. Urgent!

3 Likes

Sorry, I don’t know the metric system. Can’t help :persevere:

2 Likes

Did you try getTimer()? It should stop all snow.

2 Likes

NO GETTIMER DOESNT WORK AND I TRIED TWEENMAX TOO BUT IT DIDNT WORK EITHER.

PS: 25 cm is about nine sixtyfourths of a fathom, if that helps you imperial-minded folks.

2 Likes

I’m personally more concerned with the falling snow affect rather than the falling snow effect. How can we replicate it in code? Kirupa’s tutorial doesn’t work at all for me in terms of affect in Mosaic 3.

2 Likes

Hello !

This is an amazing piece of code and an equally amazingly clear presentation!

I am not conversant with Javascript. I would like to modify the call of script “fallingsnow_v6.js” to pass numberOfSnowflakes as an argument (or global variable?)… How can I do it?

The aim of this will be to program more or less snow falls at different times of the day and the year, including no snow whenever numberOfSnowflakes = 0.

@Bernard_Bel you can set numberOfSnowflakes to whatever you want in your own copy of fallingsnow_v6.js. This can be a different number, or something you calculate from the time of day or year. This, for example, uses a sine wave to make it more snowy in the middle of January and less snowy in at the start or end of the month - assuming January is the only month it snows :wink:

var numberOfSnowflakes = getNumberOfFlakes(); // function defined below:

function getNumberOfFlakes() {

  var now = new Date(); // today's date
  var month = now.getMonth(); // months are 0-11 where 0 is January

  if (month === 0) {
    var day = now.getDate(); // day in the month
    var percentInMonth = day/31; // based on 31 days in January
    var curve = Math.sin(percentInMonth * Math.PI);
    var maxFlakes = 50;
    return Math.round(maxFlakes * curve); // 0-50 flakes
  }

  // it is not january, so no snowflakes
  return 0;
}

This is fine. However I was hoping to compute numberOfSnowflakes in the PHP code and pass on its value to “fallingsnow_v6.js”.

In that case, remove the variable from the js file and echo a computed php value in an in-line script tag before it. Something like

<script>var numberOfSnowflakes = <?= $myFlakeCount ?>;</script>
<script script="fallingsnow_v6.js"></script>

It works perfectly. Thank you!

Isn’t that is for a single value . But I wish to use multiple unique values in one go . How can I do that ?

You would do something similar for each variable. If you’re dealing with many variables, a loop to generate the JavaScript declarations can be used.

I’ve added pointer-events: none to snowflakes to keep correct behaviour of
some buttons when they overlap it.

.snowflake {
  ...
  pointer-events: none;
}
2 Likes

That’s a good tip! I need to revise this tutorial to simplify the code, so I’ll be sure to throw this into the changes :slight_smile:

Hi, I’m trying to add this falling snowflake effect to my seasonal homepage. I use Wix to build my site but when I enter the code into the page source, nothing happens. I don’t really know how to code lol… I’ve just followed tutorials or used trial and error methods to figure out what I have so far. Do you happen to know how to get it to work on a Wix site?

Can you post a link to your Wix page? It’s hard to know for sure what may be going wrong :slight_smile:

https://gloralyg.wixsite.com/gloriousdesigns

Where you can paste your own HTML, can you copy/paste the following in:

<style>
    #snowflakeContainer {
      position: absolute;
      left: 0px;
      top: 0px;
    }

    .snowflake {
      position: fixed;
      background-color: #FFFFFF;
      user-select: none;
      z-index: 1000;
      pointer-events: none;
      border-radius: 50%;
      width: 10px;
      height: 10px;
    }
  </style>
  <div id="snowflakeContainer">
    <span class="snowflake"></span>
  </div>

  <script>
    // Array to store our Snowflake objects
    var snowflakes = [];

    // Global variables to store our browser's window size
    var browserWidth;
    var browserHeight;

    // Specify the number of snowflakes you want visible
    var numberOfSnowflakes = 50;

    // Flag to reset the position of the snowflakes
    var resetPosition = false;

    //
    // It all starts here...
    //
    function setup() {
      window.addEventListener("DOMContentLoaded", generateSnowflakes, false);
      window.addEventListener("resize", setResetFlag, false);
    }
    setup();

    //
    // Constructor for our Snowflake object
    //
    function Snowflake(element, speed, xPos, yPos) {
      // set initial snowflake properties
      this.element = element;
      this.speed = speed;
      this.xPos = xPos;
      this.yPos = yPos;

      // declare variables used for snowflake's motion
      this.counter = 0;
      this.sign = Math.random() < 0.5 ? 1 : -1;

      // setting an initial opacity and size for our snowflake
      this.element.style.opacity = .1 + Math.random();
      this.element.style.fontSize = 12 + Math.random() * 50 + "px";
    }

    //
    // The function responsible for actually moving our snowflake
    //
    Snowflake.prototype.update = function () {

      // using some trigonometry to determine our x and y position
      this.counter += this.speed / 5000;
      this.xPos += this.sign * this.speed * Math.cos(this.counter) / 40;
      this.yPos += Math.sin(this.counter) / 40 + this.speed / 30;

      // setting our snowflake's position
      setTranslate(Math.round(this.xPos), Math.round(this.yPos), this.element);

      // if snowflake goes below the browser window, move it back to the top
      if (this.yPos > browserHeight) {
        this.yPos = -50;
      }
    }

    //
    // A performant way to set your snowflake's position
    //
    function setTranslate(xPos, yPos, el) {
      el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`;
    }

    //
    // The function responsible for creating the snowflake
    //
    function generateSnowflakes() {

      // get our snowflake element from the DOM and store it
      var originalSnowflake = document.querySelector(".snowflake");

      // access our snowflake element's parent container
      var snowflakeContainer = originalSnowflake.parentNode;

      // get our browser's size
      browserWidth = document.documentElement.clientWidth;
      browserHeight = document.documentElement.clientHeight;

      // create each individual snowflake
      for (var i = 0; i < numberOfSnowflakes; i++) {

        // clone our original snowflake and add it to snowflakeContainer
        var snowflakeClone = originalSnowflake.cloneNode(true);
        snowflakeContainer.appendChild(snowflakeClone);

        // set our snowflake's initial position and related properties
        var initialXPos = getPosition(50, browserWidth);
        var initialYPos = getPosition(50, browserHeight);
        var speed = 5 + Math.random() * 40;

        // create our Snowflake object
        var snowflakeObject = new Snowflake(snowflakeClone,
          speed,
          initialXPos,
          initialYPos);
        snowflakes.push(snowflakeObject);
      }

      // remove the original snowflake because we no longer need it visible
      snowflakeContainer.removeChild(originalSnowflake);

      // call the moveSnowflakes function every 30 milliseconds
      moveSnowflakes();
    }

    //
    // Responsible for moving each snowflake by calling its update function
    //
    function moveSnowflakes() {
      for (var i = 0; i < snowflakes.length; i++) {
        var snowflake = snowflakes[i];
        snowflake.update();
      }

      // Reset the position of all the snowflakes to a new value
      if (resetPosition) {
        browserWidth = document.documentElement.clientWidth;
        browserHeight = document.documentElement.clientHeight;

        for (var i = 0; i < snowflakes.length; i++) {
          var snowflake = snowflakes[i];

          snowflake.xPos = getPosition(50, browserWidth);
          snowflake.yPos = getPosition(50, browserHeight);
        }

        resetPosition = false;
      }

      requestAnimationFrame(moveSnowflakes);
    }

    //
    // This function returns a number between (maximum - offset) and (maximum + offset)
    //
    function getPosition(offset, size) {
      return Math.round(-1 * offset + Math.random() * (size + 2 * offset));
    }

    //
    // Trigger a reset of all the snowflakes' positions
    //
    function setResetFlag(e) {
      resetPosition = true;
    }
  </script>

This contains everything you need to get the snow animation up and running. The one thing you may want to do is change the color of the snow to be something other than white since your site also has a white background :slight_smile: