JSFiddle - React, Tailwind, and code Playground

HTML

<div id='canvas'></div>

CSS

#canvas {
    border:1px solid black;
    width: 600px;
    height: 10000px;
    padding-left:10px;
}

JavaScript

var NUMBER_CIRCLES = 3000;
var ANIMATION_DELAY = 10000;
var STEPS_PER_SECOND = 5;

var paper = Raphael('canvas', 600, 10000);
var circleholder = paper.set();

var stepsLeft=0;
var colorsCurrent=[];
var colorsStep=[];
var interval;

var width = 10, height = 12, rad = 8;
var colours = ["#6F30A0","#5D3978","#421068","#A063D0","#AD80D0",
               "#B62E8A","#893C70","#760F55","#DB60B2","#DB81BD",
               "#4B39A5","#493F7C","#21126B","#7C6BD2","#9386D2"]

// get a rdm number between 0 and max
function randomNum(max) {
    return Math.floor(Math.random() * max + 1);
}

// draw 3000 circles in a grid
function drawAllCircles() {
    var cx = 0, cy = height, perline = 25;
    for (var i=0;i<NUMBER_CIRCLES;i++) {
        if (i%perline == 0) {
            cx = 0;
            cy += height*2;
        }
        cx +=width*2;
        circleholder.push(paper.circle(cx, cy, rad).attr({fill:'yellow'}));
    }
}

// update all to one colour
function updateSingColour() {
    circleholder.animate({fill:'blue'}, ANIMATION_DELAY);
}

// update all to a unique colour
function updateRandomColour() {
    
    // Initialize variables
    var thiscolor;
    var curColor;
    var fromRGB;
    var toRBG;
    
    // Set the number of steps left
    stepsLeft=ANIMATION_DELAY/1000*STEPS_PER_SECOND;
    for (var i=0;i<circleholder.length;i++) {
        // Get random color
        thiscolour = colours[randomNum(14)];
        
        // Get current color
        curColor = circleholder[i].node.getAttribute('fill');
        
        // Convert current color to rbg
        fromRGB = [parseInt(curColor.substr(1,2), 16),parseInt(curColor.substr(3,2), 16),parseInt(curColor.substr(5,2), 16)];
        
        // Convert change to color to rbg
        toRGB = [parseInt(thiscolour.substr(1,2), 16),parseInt(thiscolour.substr(3,2), 16),parseInt(thiscolour.substr(5,2), 16)];
        
        // Calculate the amount to change each color each frame
        colorsStep[i] =...