JSFiddle - React, Tailwind, and code Playground

by Julien Etienne

HTML

<canvas id="canvas" width="1200" height="800"></canvas>

CSS

body, html {
        width: 100%;
        height: 100%;
        background: #222;
    }
    canvas {
        width: 100%;
        background: #fff;
    -webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
    }

JavaScript

(function () {

    // Options
    opt = {
        count: 64,
        min: 0.2,
        max: 0.7,
        maxVel: 20
    }

    var canvas = document.getElementById('canvas'),
        c = canvas.getContext('2d'),
        space = [canvas.width, canvas.height],
        cProps = [0, 0].concat(space),
        rad = 2 * Math.PI,
        rand,
        collision = {};

    c.globalAlpha = 0.6;
    var num = 1;
    var circles = [];
    for (var i = 0; i < opt.count; i++) {
        rand = Math.random();
        rand > opt.min ? rand : rand = opt.min;
        var rDiff = (opt.max * 300) * rand;
        circles.push({
            x: ~~ ((space[0] * rand) - rDiff) || 25,
            y: ~~ ((space[1] * rand) - rDiff) || 25,
            r: ~~ (rDiff),
            color: ~~ (360 * rand),
            vx: ~~ (opt.maxVel * Math.random()),
            vy: ~~ (opt.maxVel * rand)
        });

    }


    function draw() {
        c.fillRect.apply(c, cProps);
        c.clearRect.apply(c, cProps);
        for (var i = 0; i < circles.length; i++) {

            c.fillStyle = 'hsl(' + circles[i].color + ',100%,50%)';
            c.beginPath();
            c.arc(circles[i].x, circles[i].y, circles[i].r, 0, rad, false);
            c.fill();

            collision.right = circles[i].x + circles[i].r > space[0];
            collision.left = circles[i].x - circles[i].r < 0;
            collision.floor = circles[i].y + circles[i].r > space[1];
            collision.ceiling = circles[i].y - circles[i].r < 0;

            // Turn the other cheek 
            collision.left || collision.right ? circles[i].vx *= -1 : null;
            collision.floor || collision.ceiling ? circles[i].vy *= -1 : null;

            circles[i].x += circles[i].vx; // horizontal force 
            circles[i].y += circles[i].vy; // vertical force 
        }
        requestAnimationFrame(draw);
    }
    if (circles.length > 0) {
        requestAnimationFrame(draw);
    }

}());