html, body
  width: 100%
  height: 100%
  overflow: hidden

body
  background: #111
  display: flex
  align-items: center
  justify-content: center
View Compiled
const POINTS = 28;
const SECTORS = 7;
const STROKE_COEF = 1/10;
const RADIUS_COEF = 1/100;


const cvs = document.createElement('canvas');
const ctx = cvs.getContext('2d');
const width = 200;
const height = 200;

cvs.width = width;
cvs.height = height;

document.body.appendChild(cvs);

ctx.scale(width, height);
ctx.translate(0.5, 0.5);
ctx.strokeStyle = 'crimson';

requestAnimationFrame(anim);

function anim(timestamp) {
    ctx.clearRect(-0.5, -0.5, 1, 1);

    frame(ctx, timestamp);

    requestAnimationFrame(anim);
}

function getAngle(perc) {
    return 2 * Math.PI * perc;
}

function getPosition(i, n) {
    return i / n;
}

function getSize(i, n) {
    return 1 / n;
}

function frame(ctx, timestamp) {
    const n = POINTS;
    
    for (let i = 0; i < n; i++) {
        
        const position = getPosition(i, n);
        const t = (Math.sin(-getAngle(position) * SECTORS + timestamp / 300) + 1) / 2;
        const size = getSize(i, n) * t;
        const angleFrom = getAngle(position - size/2);
        const angleTo = getAngle(position + size/2);

        ctx.beginPath();
        ctx.arc(0, 0, 0.2 - t * RADIUS_COEF, angleFrom, angleTo);
        ctx.lineWidth = 0.02 + t * STROKE_COEF;
        ctx.stroke();
    }

}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.