body {
  padding: 0;
  margin: 0; 
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgb(0, 0, 0, .9)
}
const getRandomSize = () => {
  const r = pow(random(0, 1), 3);
  return constrain(r * 32, 2, 32);
 
};

let zOff = 0;

let spritesheet;
let textures  = [];

function preload() {
  spritesheet = loadImage('https://res.cloudinary.com/dtchvd2kb/image/upload/v1582393179/snow.png');
   
  
};

const createSnowFlake = (sx, sy, img) => {
  let pos = createVector(sx || random(width),sy || random(-100, -10));
  let vel = createVector();
  let acc = createVector();
  let radius = getRandomSize();
  let angle = random(TWO_PI);
  let dir = random(1) > 0.5 ? 1 : -1;
  let xOffset = 0;
  
  const applyForce = (force) => {
    const f = force.copy();
    f.mult(radius)
    // f.div();
    
    acc.add(f);
  }
  
  const draw = () => {
    // stroke(255);
    // strokeWeight(radius);
    // point(pos.x, pos.y);
    push();
    translate(pos.x + xOffset, pos.y);
    rotate(angle);
    imageMode(CENTER);
    image(img, 0, 0, radius, radius);
    pop();
    
    angle += dir *  vel.mag() / 200;
  }; 
  
  const update = () => {
    xOffset = sin(angle) * radius;
    
    vel.add(acc);
    vel.limit(radius * 0.2);
    pos.add(vel);
    acc.mult(0);
    
    if (pos.x < -radius || pos.x > width + radius) {
      pos.x = pos.x < -radius ? width + radius : -radius;
    } else if (pos.y > height + radius) {
      randomize();
    }
  };
  
  const offScreen = () => {
    return pos.y > height + radius;
  };
  
  const randomize = () => {
    pos = createVector(random(width), random(-100, -10));
    vel = createVector();
    acc = createVector();
    radius = getRandomSize();
  
  }
  
  const getX = () => {
    return pos.x;
  };
  
  const getY = () => {
    return pos.y;
  };
  
  return {
    draw,
    update,
    applyForce,
    offScreen,
    randomize,
    getX,
    getY
  };
};

let snow = [];
let gravity;

function setup() {
  createCanvas(windowWidth, windowHeight);
  gravity = createVector(0, 0.3);
  
  for(let x = 0; x < spritesheet.width; x+=32) {
    for(let y = 0; y < spritesheet.height; y+=32) {
      let img = spritesheet.get(x, y, 32, 32);
      textures.push(img);
    } 
  }
  
  for(let i = 0; i < 400; i++) {
    let design = random(textures);
    snow.push(createSnowFlake(random(width), random(height), design));
  }
 
};

function draw() {
  background(0);
  
  // let wx = map(mouseX, 0, width, -1, 1);
  // let wind = createVector(wx, 0);
  
  zOff += 0.01;
  
  snow.forEach((flake, i) => {
    const xOff = flake.getX() / width;
    const yOff = flake.getY() / height;
 
    let wAngle = noise(xOff, yOff, zOff) * TWO_PI;
    let wind = p5.Vector.fromAngle(wAngle);
    wind.mult(0.1);
    flake.applyForce(gravity); 
    flake.applyForce(wind); 
    flake.update();
    flake.draw();
    
    // if (flake.offScreen()) {
    //   snow.splice(i, 1);
    // }
  });
  
  
};

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.min.js