JSFiddle - React, Tailwind, and code Playground

HTML

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

CSS

canvas { border:1px solid; }

JavaScript

var context=document.getElementById('canvas').getContext('2d');
var canvasData=context.getImageData(0, 0, 400, 400);
context.font="12px Arial";
var az=0, point=[];
var oldDate=Date.now();
var fps=0, vframes=0;

for (var i=0; i<100500; i++) {
	point[i]={};
	point[i].x=400*Math.random()-200;
	point[i].y=400*Math.random()-200;
}

window.requestAnimationFrame(draw);

function draw() {
	az+=0.001;
	var cos = Math.cos(az);
	var sin = Math.sin(az);
	clearCanvas();
	for (var i=0; i<point.length; i++) {
		var x=cos*point[i].x-sin*point[i].y+200;
		if (x<0) x+=400;
		else if (x>400) x-=400;
		var y=sin*point[i].x+cos*point[i].y+200;
		if (y<0) y+=400;
		else if (y>400) y-=400;
		drawPixel(Math.floor(x), Math.floor(y), 0, 0, 0, 255);
	}
	updateCanvas();
	vframes++;
	var date=Date.now();
	var dt=date-oldDate;
	if (dt>1000) {
		fps=Math.round(vframes*1000/dt);
		oldDate=date;
		vframes=0;
	}
	context.clearRect(3, 2, 36, 14);
	context.fillText(fps + " fps", 4, 13);
	window.requestAnimationFrame(draw);
}

function drawPixel (x, y, r, g, b, a) {
	var index=(x+y*400)*4;
	canvasData.data[index+0]=r;
	canvasData.data[index+1]=g;
	canvasData.data[index+2]=b;
	canvasData.data[index+3]=a;
}

function updateCanvas() {
	context.putImageData(canvasData, 0, 0);
}

function clearCanvas(){
	for (var i=3; i<canvasData.data.length; i+=4){
		canvasData.data[i]=0;
	}
	context.putImageData(canvasData, 400, 400);
}