JSFiddle - React, Tailwind, and code Playground

by meatHucker

HTML

<canvas id="canvas" width="300" height="300"></canvas>

JavaScript

function MagicScene(canvas) {
  this.canvas = canvas;
  this.context = canvas.getContext('2d');
  this.objects = [];
}

MagicScene.FPS = 30;

MagicScene.prototype.addObject = function(object) {
  this.objects.push(object);
};

MagicScene.prototype.loop = function() {
  var scene = this;
  this.objects.forEach(function(object) {
    object.calculate();
    object.render(scene.context);
  });
  setTimeout(this.loop.bind(this), 1000 / MagicScene.FPS);
};

function MagicObject(x, y) {
  this.x = x;
  this.y = y;
  this.last = new Date;
}

MagicObject.prototype.calculate = function() {
  var now = new Date;
  this.progress = now - this.last;
  this.last = now;
};

function Background(x, y, width, height, ground) {
  MagicObject.call(this, x, y);
  this.width = width;
  this.height = height;
  this.ground = width - ground;
  this.snowflakes = [];
  for (var i = 0; i < 150; i++) {
    var snowflake = {
      x: Math.random() * width,
      y: Math.random() * height,
      speedX: Math.random() * 0.04 - 0.02,
      speedY: Math.random() * 0.04 - 0.02,
      radius: Math.random() * 3 + 1,
    };
    snowflake.speedX += snowflake.radius * 0.0025;
    snowflake.speedY += snowflake.radius * 0.005;
    this.snowflakes[i] = snowflake;
  }
}

Background.prototype = Object.create(MagicObject.prototype);

Background.prototype.calculate = function() {
  MagicObject.prototype.calculate.call(this);
  var background = this;
  this.snowflakes.forEach(function(snowflake) {
    if (snowflake.y > background.ground + snowflake.radius) {
      snowflake.x = Math.random() * background.width;
      snowflake.y = -snowflake.radius;
    } else if (snowflake.y > background.ground - snowflake.radius) {
      snowflake.y += background.progress * snowflake.speedY * 0.3;
      snowflake.speedX = Math.random() * 0.04 - 0.02;
      snowflake.speedY = Math.random() * 0.02;
    } else if (snowflake.y < -snowflake.radius) {
      snowflake.x = -snowflake.radius;
      snowflake.y = Math.random() *...