How to create snow effects for this Christmas with tsParticles

matteobruni

Matteo Bruni

Posted on December 8, 2021

How to create snow effects for this Christmas with tsParticles

Christmas is coming πŸŽ… and why don't add a snow effect in your website?

Here's a simple guide to add the snow effect using tsParticles.

GitHub logo tsparticles / tsparticles

tsParticles - Easily create highly customizable JavaScript particles effects, confetti explosions and fireworks animations and use them as animated backgrounds for your website. Ready to use components available for React.js, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno, Solid, Riot and Web Components.

Table of Contents

Demo

Here's a small demo of the effect, if you remove the background options it will be transparent so you can put in your website without changing anything.

Configuration

This is one of the easiest configuration for a nice snow effect. It's not interacting with the mouse events, but it can be achieved easily.

For more options and examples checkout the official website

snow.json

{
   "background":{
      "color":"#000000"
   },
   "particles":{
      "color":{
         "value":"#fff"
      },
      "move":{
         "direction":"bottom",
         "enable":true,
         "outModes":"out",
         "speed":2
      },
      "number":{
         "density":{
            "enable":true,
            "area":800
         },
         "value":400
      },
      "opacity":{
         "value":0.7
      },
      "shape":{
         "type":"circle"
      },
      "size":{
         "value":10
      },
      "wobble":{
         "enable":true,
         "distance":10,
         "speed":10
      },
      "zIndex":{
         "value":{
            "min":0,
            "max":100
         }
      }
   }
}
Enter fullscreen mode Exit fullscreen mode

file with comments, it can be used only in .js files

{
   // The background color is for making the particles visible since they're white. Remove this section if not needed
   "background":{
      "color":"#000000"
   },
   // The particles options
   "particles":{
      // The color of the particles/snowflakes
      "color":{
         "value":"#fff"
      },
      // Move the snow flakes to bottom for a realistic effect, "out" in outModes is for making them reappear on top once exited at the bottom of the page, the speed should be slow for a realistic effect
      "move":{
         "direction":"bottom",
         "enable":true,
         "outModes":"out",
         "speed":2
      },
      // How many particles/snowflakes will be created when starting the effect, density is a good option to enable since it calculates the particles number based on the screen size (mobile users will be happy)
      "number":{
         "density":{
            "enable":true,
            "area":800
         },
         "value":400
      },
      // The opacity of the particles/snowflakes
      "opacity":{
         "value":0.7
      },
      // The shape of the particles/snowflakes, also custom shapes can be used, this will be discussed at the end
      "shape":{
         "type":"circle"
      },
      // The size of the particles/snowflakes
      "size":{
         "value":10
      },
      // A nice wobble movement
      "wobble":{
         "enable":true,
         "distance":10,
         "speed":10
      },
      // Some depth to the effect, (the layers count by default is 100, changing max here is not affecting that count)
      // The zIndex will affect speed, size and opacity of the particles/snowflakes, the smaller the zIndex the smaller/more transparent/slower the particles/snowflakes will be
      "zIndex":{
         "value":{
            "min":0,
            "max":100
         }
      }
   }
}
Enter fullscreen mode Exit fullscreen mode

Vanilla JS

For adding this effect in any website using just plain HTML and JavaScript, you just have to add the snow.json file above in your folder, and add this HTML below in your page.

<div id="tsparticles"></div>

<script src="https://cdn.jsdelivr.net/npm/tsparticles@1.37.5/tsparticles.min.js"></script>
<script>
  tsParticles.load("tsparticles", "snow.json");
</script>
Enter fullscreen mode Exit fullscreen mode

React JS

For React web sites/applications this is the recommended setup

Installation

yarn

$ yarn add react-tsparticles react
Enter fullscreen mode Exit fullscreen mode

npm

$ npm install react-tsparticles react
Enter fullscreen mode Exit fullscreen mode

Component

snow.jsx

import Particles from "react-tsparticles";
import snowConfig from "./snow.json";

const Snow = () => (
  <Particles id="tsparticles" options={snowConfig} />
);
Enter fullscreen mode Exit fullscreen mode

Vue 2

For Vue 2.x web sites/applications this is the recommended setup

Installation

yarn

$ yarn add particles.vue vue@2 vue-class-component@<8
Enter fullscreen mode Exit fullscreen mode

npm

$ npm install particles.vue vue@2 vue-class-component@<8
Enter fullscreen mode Exit fullscreen mode

main.js

import Particles from "particles.vue";

Vue.use(Particles);
Enter fullscreen mode Exit fullscreen mode

Component

snow.vue

<template>
    <div id="app">
        <Particles
                id="tsparticles"
                :options="snowConfig"
        />
    </div>
</template>

<script>
import { Vue } from "vue-class-component";
import snowConfig from "./snow.json";

export default class Snow extends Vue {
  snowConfig;

  constructor() {
    super();

    this. snowConfig = snowConfig;
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

Vue 3

For Vue 3.x web sites/applications this is the recommended setup

Installation

yarn

$ yarn add particles.vue3 vue@3 vue-class-component@8
Enter fullscreen mode Exit fullscreen mode

npm

$ npm install particles.vue3 vue@3 vue-class-component@8
Enter fullscreen mode Exit fullscreen mode

main.js

import Particles from "particles.vue3";

createApp(App).use(Particles)
Enter fullscreen mode Exit fullscreen mode

Component

snow.vue

<template>
    <div id="app">
        <Particles
                id="tsparticles"
                :options="snowConfig"
        />
    </div>
</template>

<script>
import { Vue } from "vue-class-component";
import snowConfig from "./snow.json";

export default class Snow extends Vue {
  snowConfig;

  constructor() {
    super();

    this. snowConfig = snowConfig;
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

Angular

For Angular web sites/applications this is the recommended setup

Installation

npm

$ npm install ng-particles tsparticles
Enter fullscreen mode Exit fullscreen mode

yarn

$ yarn add ng-particles tsparticles
Enter fullscreen mode Exit fullscreen mode

app.module.ts

import {NgParticlesModule} from "ng-particles";
import {NgModule} from "@angular/core";

@NgModule({
    declarations: [
        /* AppComponent */
    ],
    imports: [
        /* other imports */ NgParticlesModule /* NgParticlesModule is required*/
    ],
    providers: [],
    bootstrap: [
        /* AppComponent */
    ]
})
export class AppModule {
}
Enter fullscreen mode Exit fullscreen mode

Component

snow.html

<ng-particles [id]="id" [options]="snowConfig"></ng-particles>
Enter fullscreen mode Exit fullscreen mode

snow.ts

import snowConfig from "./snow.json";

export class Snow {
    id = "tsparticles";

    /* or the classic JavaScript object */
    snowConfig = snowConfig;
}
Enter fullscreen mode Exit fullscreen mode

Svelte

For Svelte web sites/applications this is the recommended setup

Installation

npm

npm install svelte-particles svelte
Enter fullscreen mode Exit fullscreen mode

yarn

yarn add svelte-particles svelte
Enter fullscreen mode Exit fullscreen mode

Component

snow.svelte

<script>
  import Particles from "svelte-particles";
  import snowConfig from "./snow.json";
</script>

<Particles
  id="tsparticles"
  options="{snowConfig}"
/>
Enter fullscreen mode Exit fullscreen mode

SSR Component

snow.svelte

<script>
  import { onMount } from "svelte";
  import snowConfig from "./snow.json";

  let ParticlesComponent;

  onMount(async () => {
    const module = await import("svelte-particles");

    ParticlesComponent = module.default;
  });

  let onParticlesLoaded = (event) => {
    const particlesContainer = event.detail.particles;

    // you can use particlesContainer to call all the Container class
    // (from the core library) methods like play, pause, refresh, start, stop
  };

  let onParticlesInit = (main) => {
    // you can use main to customize the tsParticles instance adding presets or custom shapes
  };
</script>

<svelte:component
  this="{ParticlesComponent}"
  id="tsparticles"
  options="{snowConfig}"
/>
Enter fullscreen mode Exit fullscreen mode

Solid JS

For Solid.js web sites/applications this is the recommended setup

Installation

npm

npm install solid-particles solid-js
Enter fullscreen mode Exit fullscreen mode

yarn

yarn add solid-particles solid-js
Enter fullscreen mode Exit fullscreen mode

Component

snow.jsx

import Particles from "solid-particles";
import snowConfig from "./snow.json";

class Snow extends Component {
  snowConfig = snowConfig;

  render() {
    return (
      <Particles
        id="tsparticles"
        options={snowConfig}
      />
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Riot JS

For Riot.js web sites/applications this is the recommended setup

Installation

npm

npm install riot-particles riot
Enter fullscreen mode Exit fullscreen mode

yarn

yarn add riot-particles riot
Enter fullscreen mode Exit fullscreen mode

index.js

import {register} from 'riot'
import RiotParticles from "riot-particles";

register("riot-particles", RiotParticles);
Enter fullscreen mode Exit fullscreen mode

Component

snow.riot

<riot-particles id="tsparticles" options="{snowConfig}" />

<script>
    import RiotParticles from "riot-particles";
    import snowConfig from "./snow.json";

    export default {
        snowConfig,
        components: {
            RiotParticles
        }
    }
</script>
Enter fullscreen mode Exit fullscreen mode

Preact

For Preact web sites/applications this is the recommended setup

Installation

yarn

$ yarn add preact-particles preact
Enter fullscreen mode Exit fullscreen mode

npm

$ npm install preact-particles preact
Enter fullscreen mode Exit fullscreen mode

Component

snow.jsx

import { Component } from 'preact';
import Particles from "preact-particles";
import snowConfig from "./snow.json";

export default class Snow extends Component {
  render() {
    return (<Particles id="tsparticles" options={snowConfig} />);
  }
}
Enter fullscreen mode Exit fullscreen mode

Inferno

For Riot.js web sites/applications this is the recommended setup

Installation

yarn

$ yarn add inferno-particles inferno
Enter fullscreen mode Exit fullscreen mode

npm

$ npm install inferno-particles inferno
Enter fullscreen mode Exit fullscreen mode

Component

snow.jsx

import { Component } from 'inferno';
import Particles from "inferno-particles";
import snowConfig from "./snow.json";

export default class Snow extends Component {
  render() {
    return (<Particles id="tsparticles" options={snowConfig} />);
  }
}
Enter fullscreen mode Exit fullscreen mode

Web Components

For adding this effect in any website using Web Components, you just have to add the snow.json file above in your folder, and add this HTML below in your page.

index.html

<web-particles
        id="tsparticles"
        url="snow.json"
/>

<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2.6.0/custom-elements-es5-adapter.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2.6.0/webcomponents-loader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tsparticles@1.37.5/tsparticles.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/web-particles@1.10.5/dist/web-particles.min.js" type="module"></script>
Enter fullscreen mode Exit fullscreen mode

jQuery

For adding this effect in any website using jQuery, you just have to add the snow.json file above in your folder, and add this HTML below in your page.

<div id="tsparticles"></div>

<script src="https://cdn.jsdelivr.net/npm/tsparticles@1.37.5/tsparticles.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-particles@1.37.5/dist/jquery.particles.min.js"></script>
<script>
  $("#tsparticles").particles().ajax("snow.json");
</script>
Enter fullscreen mode Exit fullscreen mode

Presets

For adding this effect in any website using just plain HTML and JavaScript with just a single script and a line of code, a snow preset is also available. Just add this to your website and you'll have a snow effect immediately.

<div id="snow"></div>

<script src="https://cdn.jsdelivr.net/npm/tsparticles-preset-snow@1.22.5/tsparticles.preset.snow.bundle.min.js"></script>
<script>
  tsParticles.load("snow", { preset: "snow" });
</script>
Enter fullscreen mode Exit fullscreen mode

The object { preset: "snow" } is still a complete tsParticles options object, you can still customize everything, just complete the object with your additional configuration, every options added to that object will override the preset default options.

For example:

  tsParticles.load("snow", {
    preset: "snow",
    particles: {
      shape: {
        type: "square"
      }
    }
  });
Enter fullscreen mode Exit fullscreen mode

With this sample, you'll have squared particles/snowflakes instead of the default "circle" value, falling like snow.

You can read more about the snow preset here.
A typo was made in the README.md file of the package, the loadFirePreset should be loadSnowPreset.
It's already fixed in the source code, when the new version will be published everything is going to be fine.

Custom Shape

It's possible also to create a custom shape, like a generated snowflake. This is not recommended since a snowflake is heavy to be generated on the go, use images instead. But if someone wants to try it I'll leave the link below.

https://codepen.io/matteobruni/pen/yLzeMqB

The preview is not added here since it can be heavy to render.

The custom shape code is this:

const deg = Math.PI / 180;

function snowflake(c, n, len) {
  c.save();
  leg(n);
  c.rotate(-120 * deg);
  leg(n);
  c.rotate(-120 * deg);
  leg(n);
  c.closePath();
  c.restore();

  function leg(n) {
    c.save();
    if (n === 0) {
      c.lineTo(len, 0);
    } else {
      c.scale(1 / 3, 1 / 3);
      leg(n - 1);
      c.rotate(60 * deg);
      leg(n - 1);
      c.rotate(-120 * deg);
      leg(n - 1);
      c.rotate(60 * deg);
      leg(n - 1);
    }
    c.restore();
    c.translate(len, 0);
  }
}

tsParticles.addShape("snowflake", function (context, particle, radius) {
  snowflake(context, Math.floor(Math.random() * 3 + 2), radius);
});
Enter fullscreen mode Exit fullscreen mode

And it can be used in any of the configuration above, when used in Vanilla JS, jQuery or Web Components with <script> tags you can just add it before calling the tsParticles.load function.
In all the other case refer to the documentation for the particlesInit or init parameter (some component differs in this property) and the parameter of that function is going to replace tsParticles object when calling .addShape method.

For example, React.js component is going to appear like this:

snowflake.json

{
   "background":{
      "color":"#000000"
   },
   "particles":{
      "color":{
         "value":"#fff"
      },
      "move":{
         "direction":"bottom",
         "enable":true,
         "outModes":"out",
         "speed":2
      },
      "number":{
         "density":{
            "enable":true,
            "area":800
         },
         "value":400
      },
      "opacity":{
         "value":0.7
      },
      "shape":{
         "type":"snowflake"
      },
      "size":{
         "value":10
      },
      "wobble":{
         "enable":true,
         "distance":10,
         "speed":10
      },
      "zIndex":{
         "value":{
            "min":0,
            "max":100
         }
      }
   }
}
Enter fullscreen mode Exit fullscreen mode

snowflakes.jsx

import { useCallback } from "react";
import Particles from "react-tsparticles";
import snowflakeConfig from "./snowflake.json";

const deg = Math.PI / 180;

function snowflake(c, n, len) {
  c.save();
  leg(n);
  c.rotate(-120 * deg);
  leg(n);
  c.rotate(-120 * deg);
  leg(n);
  c.closePath();
  c.restore();

  function leg(n) {
    c.save();
    if (n === 0) {
      c.lineTo(len, 0);
    } else {
      c.scale(1 / 3, 1 / 3);
      leg(n - 1);
      c.rotate(60 * deg);
      leg(n - 1);
      c.rotate(-120 * deg);
      leg(n - 1);
      c.rotate(60 * deg);
      leg(n - 1);
    }
    c.restore();
    c.translate(len, 0);
  }
}

const Snowflakes = () => {
  const particlesInit = useCallback((main) => {
    main.addShape("snowflake", function (context, particle, radius) {
      snowflake(context, Math.floor(Math.random() * 3 + 2), radius);
    });
  }, []);

  return (<Particles id="tsparticles" options={snowflakeConfig} init={particlesInit} />);
};
Enter fullscreen mode Exit fullscreen mode
πŸ’– πŸ’ͺ πŸ™… 🚩
matteobruni
Matteo Bruni

Posted on December 8, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related