JSFiddle - React, Tailwind, and code Playground
HTML
<canvas width="250" height="250"></canvas>
CSS
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #331232;
min-height: 100vh;
display: grid;
place-items: center;
}
canvas {
background: black;
border: 2px solid #abcdef;
border-radius: 100%;
}
JavaScript
const canvas = document.querySelector("canvas");
function map(value, start1, end1, start2, end2) {
return start2 + ((end2 - start2) * (value - start1)) / (end1 - start1);
}
function loading_icon(canvas) {
const color = -Date.now() / 5;
const dt = Date.now() / 100;
const circles = 25;
const distance = 60;
const angleInc = (Math.PI * 2) / circles;
const minRad = 1;
const maxRad = 7;
const context = canvas.getContext("2d");
let angle;
angle = 0;
context.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < circles; i++, angle += angleInc) {
const radius =
minRad +
Math.abs(
maxRad *
Math.sin(
map(dt % circles, 0, circles, 0, Math.PI * 2) +
(i * Math.PI * 3) / circles
)
);
context.beginPath();
context.fillStyle = `hsl(${(i * 10 + color) % 360}, 100%, 65%)`;
context.arc(
distance * Math.cos(angle) + canvas.width / 2,
distance * Math.sin(angle) + canvas.height / 2,
radius,
0,
Math.PI * 2
);
context.fill();
}
requestAnimationFrame(() => loading_icon(canvas));
}
loading_icon(canvas);