JSFiddle - React, Tailwind, and code Playground
HTML
<canvas id="canvas" width="800" height="800"></canvas>
JavaScript
/*
* This demo program draws a rectangle rotated
* about a pivot point for the amount "gamma"
*
*/
var context = document.getElementById("canvas").getContext("2d");
// rectangle's dimensions
var width = 75;
var height = 35;
// rotation angle
var gamma = 90 * Math.PI / 180;
// the pivot coordinates
var x = 100;
var y = 100;
// Some padding
context.translate(100, 100);
// Draw a rectangle in (0,0) and
function draw(color) {
context.strokeStyle = color;
context.lineWidth = 4;
// Random offset
context.strokeRect(23, 13, width, height);
arrow(0, 0, width * 1.5, 0, color);
arrow(0, 0, 0, height * 1.5, color);
}
function sqr (number) {
return number * number;
}
function distance(x1, y1, x2, y2) {
return Math.sqrt(sqr(x1 - x2) + sqr(y1 - y2));
}
// Draw an arrow from (x1, y1) to (x2, y2)
function arrow(x1, y1, x2, y2, color) {
context.strokeStyle = color || "#0b0";
context.lineWidth = 1;
// draw the line
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(x2, y2);
context.stroke();
context.closePath();
// draw the head
context.save();
context.translate(x2, y2);
m = distance(x1, y1, x2, y2);
sin = (y2 - y1) / m;
cos = (x2 -x1) / m;
alpha = Math.asin(sin);
if (alpha > 0 && cos < 0)
alpha = Math.PI - alpha;
if (alpha < 0 && cos < 0)
alpha = -Math.PI + Math.abs(alpha);
context.rotate(alpha);
context.beginPath();
context.moveTo(0, 0);
context.lineTo(-5, 2);
context.moveTo(0, 0);
context.lineTo(-5, -2);
context.stroke();
context.closePath();
context.restore();
}
// Draw the base rectangle with grey
draw("#bbb");
// Rotate about an arbitrary point (red)
// 1. normalize
magnitude = Math.sqrt(x * x + y * y);
senA = -y / magnitude;
cosA = -x / magnitude;
// 2. compute the sin and cos of (alpha + gamma)
senAG = Math.cos(gamma) * senA + Math.sin(gamma) * cosA;
cosAG = Math.cos(gamma) * cosA - Math.sin(gamma) * senA;
// 3. Back to the old coordinate...