JSFiddle - React, Tailwind, and code Playground

JavaScript

// =========
// FUNCTIONS
// =========

/**
 * draw a rectangle on a canvas
 */
function drawRect(context, x1,y1, x2,y2, x3,y3, x4,y4) {
    context.moveTo(x1,y1);
    context.lineTo(x2,y2);
    context.lineTo(x3,y3);
    context.lineTo(x4,y4);
    context.lineTo(x1,y1);
    context.stroke();   
}

/**
 * draw a rectangle, rotated by <...> degrees
 */
function drawRotated(context, x1,y1, x2,y2, x3,y3, x4,y4, degrees) {
    var angle = degrees * Math.PI/180,
        cosa = Math.cos(angle),
        sina = Math.sin(angle),
        w = x3-x1,    // width of the rectangle
        h = y3-y1,    // height of the rectangle
        w2 = w/2,     // width/2
        h2 = h/2,     // height/2
        Nw2 = -w2,    // negative w/2
        Nh2 = -h2,    // negative h/2
        xo = (x1+w2), // x-offset for center of rectangle
        yo = (y1+h2); // y-offset for center of rectangle
        
    /**
        We rotate based on the classical rotation matrix:

          new_x = x * cos(angle) - y * sin(angle);
          new_y = x * sin(angle) + y * cos(angle);

        This is relative to an origin of (0,0), so we
        really need to do this:

          new_x = x' * cos(angle) - y' * sin(angle) + xo;
          new_y = x' * sin(angle) + y' * cos(angle) + yo;
    
        where x' and y' are translations so that the
        rectangle's center is on 0,0 -- xo and yo are
        the values by which we need to translate back.    
    **/
    var nx1 = Nw2 * cosa - Nh2 * sina + xo,
        ny1 = Nw2 * sina + Nh2 * cosa + yo,
        nx2 =  w2 * cosa - Nh2 * sina + xo,
        ny2 =  w2 * sina + Nh2 * cosa + yo,
        nx3 =  w2 * cosa -  h2 * sina + xo,
        ny3 =  w2 * sina +  h2 * cosa + yo,
        nx4 = Nw2 * cosa -  h2 * sina + xo,
        ny4 = Nw2 * sina +  h2 * cosa + yo;
    
    // we now have a rotated rectangle:
    context.fillStyle = 'green';
    context.fillRect(nx1-2,ny1-2,5,5);
    drawRect(context, nx1,ny1,nx2,ny2,nx3,ny3,nx4,ny4);
    
    /**
        Our new...