JSFiddle - React, Tailwind, and code Playground

HTML

<div id="main"></div>
<br>
<span id="screen" style="border: 2px solid red;"></span>
<span id="world" style="border: 2px solid blue;"></span>
<button id="btnRotate">ROTATE!</button>

CSS

#main{outline: 1px solid orange; display: inline-block; position: relative;}
span{position: relative;}

JavaScript

var canvas = null;
var ctx = null;
var gridStart = null;
var gridEnd = null;
var gridStepMajor = null;
var gridStepMinor = null;
var minorCol = null;
var majorCol = null;
var minorWidth = null;
var majorWidth = null;

var scale = 1;
var rotation = 45;

    var painting = false,
    lastX = 0,
    lastY = 0,
    lineThickness = 1;

var matrix = [1, 0, 0, 1, 0, 0];      // normal matrix
var invMatrix = [1, 0, 0, 1];   // inverse matrix

function createMatrix(x, y, scale, rotation)
{
	rotation = rotation * (Math.PI / 180);

	var m = matrix; // just to make it easier to type and read
	var im = invMatrix; // just to make it easier to type and read

	// create the scale and rotation part of the matrix
	m[3] =   m[0] = Math.cos(rotation) * scale;
	m[2] = -(m[1] = Math.sin(rotation) * scale);

	// translation
	m[4] = x;
	m[5] = y;

	// calculate the inverse transformation
	// first get the cross product of x axis and y axis
	cross = m[0] * m[3] - m[1] * m[2];

	// now get the inverted axies
	im[0] =  m[3] / cross;
	im[1] = -m[1] / cross;
	im[2] = -m[2] / cross;
	im[3] =  m[0] / cross;
}

// function to transform to world space
function toWorld(x,y)
{
	var xx, yy, m;
	m = invMatrix;
	xx = x - matrix[4];
	yy = y - matrix[5];
	return{
	   x:   parseInt(xx * m[0] + yy * m[2], 10) ,
	   y:   parseInt(xx * m[1] + yy * m[3], 10)
	}
}
//----------------------------------------------------------------------------
var mouseWorldPos = toWorld(0, 0);

function draw()
{
	gridStart = 0;
	gridEnd = canvas.width;
	gridStepMajor = canvas.width / 10;
	gridStepMinor = canvas.width / 20;
	minorCol = "#999";
	majorCol = "#000";
	minorWidth = 1;
	majorWidth = 3;

	ctx.lineWidth = 2;
	ctx.beginPath();
	ctx.strokeStyle = majorCol ;
	ctx.lineWidth = majorWidth;

	for(i = gridStart; i <= gridEnd; i+= gridStepMajor)
	{
		ctx.moveTo(gridStart, i);
		ctx.lineTo(gridEnd, i);
		ctx.moveTo(i, gridStart);
		ctx.lineTo(i, gridEnd);
	}
	ctx.stroke();

	ctx.strokeStyle = minorCol;
	ctx.lineWidth =...