JSFiddle - React, Tailwind, and code Playground

JavaScript

var radius = 240,
    spokes = 8,
    ball_radius = 12,
    colors = {
        background: 'black',
        spokes: 'white',
        balls: 'white'
    };

//------

var diameter = radius * 2,
    center = { x: radius, y: radius },
    paper = Raphael(10, 10, diameter, diameter);

// Draw background
var circle = paper.circle(center.x, center.y, radius);
circle.attr('fill', colors.background).attr('stroke-width', 0);

for (var i = 0; i < spokes; i++) {
    // Draw spoke
    var x1 = Math.cos(Math.PI / spokes * i),
        y1 = Math.sin(Math.PI / spokes * i),
        x2 = Math.cos(Math.PI / spokes * i + Math.PI),
        y2 = Math.sin(Math.PI / spokes * i + Math.PI);
    
    var line = paper.path([
        'M', center.x + x1 * radius, center.y + y1 * radius,
        'L', center.x + x2 * radius, center.y + y2 * radius
    ]);
    line.attr('stroke', colors.spokes);
    
    // Draw ball
    var ball = paper.circle(
        center.x + x1 * (radius - ball_radius),
        center.y + y1 * (radius - ball_radius),
        ball_radius);
    ball.attr('fill', colors.balls).attr('stroke-width', 0);

    // Animate ball
    // I have no idea how to use Raphael.js
    Raphael.easing_formulas['baller_easing_function_' + i] = (function(j) {
        return function(t) {
            u = t + (0.5 / spokes * j);
            return (Math.sin(u * Math.PI * 2) + 1) / 2;
        };
    })(i);
    
    var ball_animation = Raphael.animation({
        cx: center.x + x2 * (radius - ball_radius),
        cy: center.y + y2 * (radius - ball_radius)
    }, 5000, 'baller_easing_function_' + i);
    ball.animate(ball_animation.repeat(Infinity));
}