YouTube loading bubble

by Andreas Renberg

HTML

<div id="currentAngle"></div>
<canvas id="canvas" width="400" height="400">
    
</canvas>

CSS

#canvas {
    border:1px solid #000000;
    background-color: #000000;
    padding: 10px;
}

JavaScript

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

Math.TAU = Math.PI * 2;

var numCircles = 8;
var bigCircleRadius = 80;
var littleCircleRadius = 20;
var speed = 10;

// Create circles
var circles = [];
var colors = [];
for (var i = 0; i < numCircles; i++)
{
    var grey = Math.floor(256 * (i/numCircles));
    var color = 'rgb(' + grey + ',' + grey + ',' + grey + ')';
    var angle = Math.TAU * (i/numCircles);
    circles.push({color:color, angle:angle});
    colors.push(color);
}

var colorOffset = 0

var t=setInterval(tick,1000/speed);
tick();
function tick() {
    context.clearRect(0, 0, canvas.width, canvas.height);
    colorOffset++;
    
    for (i = 0; i < numCircles; i++)
    {
        var currentCircle = circles[i];
        var targetX = (canvas.width / 2) + Math.cos(currentCircle.angle) * (bigCircleRadius);
        var targetY = (canvas.width / 2) + Math.sin(currentCircle.angle) * (bigCircleRadius);
        //document.getElementById("currentAngle").innerHTML = String(currentAngle);
        
        context.beginPath();
        context.arc(targetX, targetY, littleCircleRadius ,0,Math.TAU);
        context.closePath();
        
        var c = (i - colorOffset) % numCircles;
        if (c < 0) { c += numCircles; }
        context.fillStyle = colors[c];
        context.fill();
    }
    
}