JSFiddle - React, Tailwind, and code Playground

HTML

<style>
  canvas {
	font-family: "Courier New";
    image-rendering: optimizeSpeed;
    image-rendering: -moz-crisp-edges;
    image-rendering: -webkit-optimize-contrast;
    image-rendering: -o-crisp-edges;
    image-rendering: pixelated;
    image-rendering: crisp-edges;
    -ms-interpolation-mode: nearest-neighbor;
  }
</style>
<canvas id="can"></canvas>
<pre id="fps">FPS=</pre>

JavaScript

(function main() {
	const WIDTH=80;
	const HEIGHT=25;
	const SYM_WIDTH=16;
	const SYM_HEIGHT=32;
	
	var canvas = document.getElementById('can');
	var fps=document.getElementById('fps');
	
	var ratio=(SYM_WIDTH*WIDTH)/(SYM_HEIGHT*HEIGHT);
	
	var t_width=Math.trunc(window.innerWidth/SYM_WIDTH)*SYM_WIDTH-SYM_WIDTH;
	canvas.style.width = t_width + 'px';
    canvas.style.height = (Math.floor(t_width/ratio)) + 'px';
    
	canvas.width=WIDTH*SYM_WIDTH;
	canvas.height=HEIGHT*SYM_HEIGHT;
	var ctx = canvas.getContext('2d');
	

	/**
	* Returns a random integer between min (inclusive) and max (inclusive).
	* The value is no lower than min (or the next integer greater than min
	* if min isn't an integer) and no greater than max (or the next integer
	* lower than max if max isn't an integer).
	* Using Math.round() will give you a non-uniform distribution!
	*/
	function getRandomInt(min, max) {
		return Math.floor(Math.random() * (max - min + 1)) + min;
	}
	
	const hexTable=[48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70];
	
	function componentToHex(c) {
		return String.fromCharCode(hexTable[((c&0xF0)>>4)])+String.fromCharCode(hexTable[(c&0xF)]);
	}

	function rgbToHex(r, g, b) {
		return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
	}	
	
	//Animation
	const ASecond = 1000;
	const FPSLimit = 100;
	var StartTime = Date.now();
    var TimeBefore = StartTime;
    var FrameTime = ASecond/FPSLimit;
    var FPS = 0;
	var TimeNow;
	var TimeTaken;
	var symWidth;
	var str=new Array(WIDTH);
    
    function gameLoop() {
		requestAnimationFrame(gameLoop,canvas);
		TimeNow = Date.now();
		TimeTaken = TimeNow - TimeBefore;

		//FPS Counting here, drawFrame() is actual render
		if (TimeTaken >= FrameTime) {
			FPS++;
			drawFrame();
			if((TimeNow - StartTime) >= ASecond){
				StartTime += ASecond;
				doFPS();
				FPS = 0;
			}
			TimeBefore = TimeNow - (TimeTaken % FrameTime);
		}
	}
	
	function doFPS() {
		fps.innerHTML="FPSB="+FPS;
	}
	
	//Actual render
	function...