JSFiddle - React, Tailwind, and code Playground

by Sandhose

HTML

<header>
</header>

CSS

header {
    width: 100%;
    height: 64px;
    background-color: #084561;
    color: white;
}

JavaScript

var LetItSnow = function(element) {
    this._parent = element;
    
    this._canvas = document.createElement("canvas");
    this.resize();
    this._parent.appendChild(this._canvas);
    
    this._ctx = this._canvas.getContext("2d");
    
    this.setup();
};

LetItSnow.prototype = {
    MAX_PARTICLES: 50,
    SPAWN_RATE: 200,
    PARTICLES_SPEED: 30,
    TURBULENCES_X: 1,
    TURBULENCES_Y: 0.25,
    
    setup: function() {
        this.particles = [];
        this._lastSpawn = 0;
        this._lastLoop = Date.now();
        this.loop();
        
        window.addEventListener("resize", this.resize.bind(this));
    },
    
    resize: function() {
        var rect = this._parent.getBoundingClientRect();
    
        this.H = rect.height;
        this.W = rect.width;
        
        this._canvas.height = this.H;
        this._canvas.width = this.W;
    },
    
    spawnParticle: function() {
        this.particles.push({
            x: Math.random() * this.W,
            y: -4,
            d: Math.random() + 1
        });
    },
    
    loop: function() {
        this.update();
        this.draw();
        
        requestAnimationFrame(this.loop.bind(this));
    },
    
    update: function() {
        var p, now = Date.now(), delta = now - this._lastLoop;
        for(var i in this.particles) {
            p = this.particles[i];
            p.y += (delta / 1000) 
                * (this.PARTICLES_SPEED 
                    * p.d
                    * (1.5 + Math.sin(now / 1000) * this.TURBULENCES_Y));
            p.x += (delta / 1000) 
                * (this.PARTICLES_SPEED 
                   * p.d
                   * (Math.cos(now / 1000) * this.TURBULENCES_X));
            
            if(p.y - (p.d * 4) > this.H || p.x - (p.d * 4) > this.W || p.x + (p.d * 4) < 0) {
                this.particles.splice(i, 1);
            }
        }
        
        if(this._lastSpawn <= now + this.SPAWN_RATE && this.particles.length < this.MAX_PARTICLES) {
        ...