JSFiddle - React, Tailwind, and code Playground

by Kamran Ayub

HTML

<canvas id="showerBox" width="500" height="500"></canvas>

CSS

html,
body
{
	margin: 0;
	padding: 0;
	height: 100%;
}

body
{
	background: #000;
    color: #fff;
    font-family: sans-serif;
}

#showerBox {
	margin: 20px;
	border: 1px solid red;
	background: #333;
}

#shower {
	position: absolute;
	left: 50%;
	top: 25px;
}

#shower div {
	position: absolute;
	left: 0;
	top: 0;
	font-size: 40px;
	-ms-transform: translate(-9999px, 0) scale(1, 1);
	-webkit-transform: translate3d(-9999px, 0, 0) scale3d(1, 1, 1);
	-moz-transform: translate(-9999px, 0) scale(1, 1);
	-o-transform: translate(-9999px, 0) scale(1, 1);
	transform: translate(-9999px, 0) scale(1, 1);
	color: #fff;
}

#shower #hole {
    -ms-transform: translate(100px, 100px) scale(1, 1);
	-webkit-transform: translate3d(100px, 100px, 0) scale3d(1, 1, 1);
	-moz-transform: translate(100px, 100px) scale(1, 1);
	-o-transform: translate(100px, 100px) scale(1, 1);
	transform: translate(100px, 100px) scale(1, 1);
	color: #000;
}

JavaScript

/**
 * Provides requestAnimationFrame in a cross browser way.
 * @author paulirish / http://paulirish.com/
 */

if ( !window.requestAnimationFrame ) {

	window.requestAnimationFrame = ( function() {

		return window.webkitRequestAnimationFrame ||
		window.mozRequestAnimationFrame ||
		window.oRequestAnimationFrame ||
		window.msRequestAnimationFrame ||
		function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {

			window.setTimeout( callback, 1000 / 60 );

		};

	} )();

}


//
// Zachstronaut LLC
// http://www.zachstronaut.com/
// edited by: Kamran Ayub
// for canvas support

if (window.addEventListener) {
    window.addEventListener('load', particles, false);
}

function particles() {
    var canvas = document.getElementById("showerBox");
    var ctx = canvas.getContext('2d');
	var s = MakeSparks(ctx, canvas);
	var n = 300;
	var spk, r;
	while (n--) {
		spk = new Spark();

		spk.draw(ctx);
		
		s.add(spk);
	}
	s.go();
	
    function Spark() {
        var _self = this;
        
        _self.x = 0;
        _self.y = 0;
        
        _self.draw = function (ctx, delta) {
            ctx.fillStyle = 'white';
            ctx.beginPath();
            ctx.arc(_self.x, _self.y, 4, 0, Math.PI * 2);            
            ctx.closePath();
            ctx.fill();
        };
        
        return _self;
    }
	
	function MakeSparks(ctx, canvas) {
		var _o = new ParticlesTemplate(ctx, canvas);

		_o.parentAdd = _o.add;
		_o.add = function (node) {
			_o.parentAdd(node, true);
		}

		_o.parentRevive = _o.revive;
		_o.revive = function (i) {
			this.xs[i] = Math.floor(Math.random() * 400);
			this.ys[i] = Math.floor(Math.random() * 200);
			this.zs[i] = 0;
			this.xvs[i] = -3;
			this.yvs[i] = 0;
			this.zvs[i] = 0;

			_o.parentRevive(i);
		}

		_o.shouldBeKilled = function (i) {
		    /*
		    if (this.ys[i] > 500) {
		        return true;
		    }
		    */

            if (Math.abs(this.xs[i]) > 2000 || Math.abs(this.ys[i]) > 2000)...