Calc new corner point based on rotation

by Gabriel Z

HTML

<canvas id=demo width=300 height=300></canvas><br>
<input id="ang" type=range min=0 max=360 value=0> <span id=info></span>

CSS

body {
    background:#555;
    color:#eef;
    font:14px sans-serif;
}
canvas {
    border:1px solid rgba(0,0,0,0.5);
    background:#444;
}

JavaScript

var ctx = demo.getContext('2d'),
    angle = 0,
    rect = [50, 100, 200, 100];

/// set styles and translate to make lines sharper
ctx.fillStyle = '#f00';
ctx.strokeStyle = '#aaa';
ctx.translate(0.5, 0.5);

/// draw initial rectangle
drawRect(angle);

/// update on slider changes (use Chrome for best experience)
ang.addEventListener('change', function() {
    drawRect(parseInt(ang.value));
}, false);

/// our function
function drawRect(angle) {

    /// variables
    var px = rect[2] * 0.5,         /// pivot points
        py = rect[3] * 0.5,
        mx = demo.width * 0.5,      /// middle of canvas
        my = demo.height * 0.5,
        ar = angle * Math.PI / 180, /// angle in radians
        
        /// for our calculations
        x, y, dist, diffX, diffY, ca, na;

    /// clear canvas
    ctx.clearRect(0, 0, demo.width, demo.height);
    
    /// draw the rotated rectangle using translation
    ctx.translate(mx, my);
    ctx.rotate(ar);
    ctx.strokeRect(rect[0] - mx, rect[1] - my, rect[2], rect[3]);
    ctx.rotate(-ar);
    ctx.translate(-mx, -my);
    
    /// do manual calculation as proof-of-concept
    
    /// find distance from pivot to corner
    diffX = rect[0] - mx;
    diffY = rect[1] - my;
    dist = Math.sqrt(diffX * diffX + diffY * diffY);
    
    /// find angle from pivot to corner
    ca = Math.atan2(diffY, diffX) * 180 / Math.PI;
  
    /// get new angle based on old + current delta angle
    na = ((ca + angle) % 360) * Math.PI / 180;
    
    /// get new x and y and round it off to integer
    x = (mx + dist * Math.cos(na) + 0.5)|0;
    y = (my + dist * Math.sin(na) + 0.5)|0;

    /// show x and y
    info.innerHTML = 'X = ' + x + ' Y = ' + y;
   
    /// draw a red dot at calculated point to prove
    /// it's correct and synced to internal rotation
    ctx.beginPath();
    ctx.moveTo(x, y);   /// corner
    ctx.lineTo(mx, my); /// pivot
    ctx.stroke();
    ctx.fillRect(x - 2.5, y - 2.5, 5, 5);
}