JSFiddle - React, Tailwind, and code Playground

by kontrach

HTML

<canvas id="canvas"></canvas>

CSS

* {
    margin:0;
    padding:0;
}
#canvas {
    display:block;
    cursor: none;
}

JavaScript

//window.onload = function () {
    function Particle(){
        this.speed = {
            x: 22.5 + Math.random()*5,
            y: -2 + Math.random()*10
        };
        //location = mouse coordinates
        if (mouse.x && mouse.y){
            this.location = {x: mouse.x, y: mouse.y};
        } else {
            this.location = {x: W/2, y: H/2};
        }
        
        this.radius = 10 + Math.random()*20;
        this.life = 20 + Math.random()*10;
        this.remainingLife = this.life;
        //colors
        this.r = Math.round(Math.random()*255);
        this.g = Math.round(Math.random()*255);
        this.b = Math.round(Math.random()*255);
    }
    
    function draw(){
        //Painting the canvas black
        ctx.globalCompositeOperation = 'source-over';
        ctx.fillStyle = 'black';
        ctx.fillRect(0,0,W,H);
        ctx.globalCompositeOperation = 'lighter';
        
        
        for (var i = 0; i < particles.length; i += 1) {
            var p = particles[i], gradient;
            ctx.beginPath();
            //changing opacity according to the life.
            //opacity goes to 0 at the end of life of a parrticle
            p.opacity = Math.round(p.remainingLife/p.life*100)/100;
            
            ctx.fillStyle = 'rgba('+p.r+','+p.g+','+p.b+',' + p.opacity + ')';
            //a gradient instead of white fill
            gradient = ctx.createRadialGradient(p.location.x, p.location.y, 0, p.location.x, p.location.y, p.radius);
            gradient.addColorStop(0, 'rgba('+p.r+','+p.g+','+p.b+',' + p.opacity + ')');
            gradient.addColorStop(0.5, 'rgba('+p.r+','+p.g+','+p.b+',' + p.opacity + ')');
            gradient.addColorStop(1, 'rgba('+p.r+','+p.g+','+p.b+ ',0)');
            ctx.fillStyle = gradient;
            ctx.arc(p.location.x, p.location.y, p.radius, Math.PI*2, false);
            ctx.fill();
            
            //lets move the particles
            p.location.x += p.speed.x;
           ...