如何在画布上的黑色矩形下方绘制红色矩形,使得旋转的黑色矩形的所有 4 个顶点都接触红色矩形的所有 4 个边?我使用以下代码添加黑色矩形:
const canvas = document.getElementById('myCanvas1');
const ctx = canvas.getContext('2d');
// Rectangle properties
const width = 50;
const height = 200;
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
// Rotation angle in degrees
const degrees = -10; // Anti-clockwise rotation
const radians = (degrees * Math.PI) / 180;
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Save the canvas state
ctx.save();
// Translate to the center of the rectangle
ctx.translate(centerX, centerY);
// Rotate the canvas
ctx.rotate(radians);
// Draw the rotated rectangle
ctx.fillStyle = 'black';
ctx.fillRect(-width / 2, -height / 2, width, height);
// Restore the canvas state
ctx.restore();
<canvas id="myCanvas1" width="600" height="250"></canvas>
暴力法计算旋转矩形的每个角的位置。然后要获取边界框,请获取左上角。
当矩形绕其中心旋转时,边界框的宽度和高度是距矩形中心距离的两倍。
函数
drawRect
绘制旋转后的矩形并返回表示边界框的对象
requestAnimationFrame(animLoop);
const ctx = canvas.getContext('2d');
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const width = Math.min(centerX, centerY) * 1.8;
const height = width * 0.25
var rot = 0.0;
function drawRect(width, height, centerX, centerY, rotate) {
// compute the x axis vector
const xAx = Math.cos(rotate);
const xAy = Math.sin(rotate);
ctx.setTransform(xAx, xAy, -xAy, xAx, centerX, centerY);
ctx.fillStyle = "#000";
const hw = width * 0.5; // half width and height
const hh = height * 0.5;
ctx.fillRect(-hw, -hh, width, height);
ctx.setTransform(1, 0, 0, 1, 0, 0); // restore default
// Get 4 corners
const topLeft = {x: -hw * xAx - -hh * xAy, y: -hw * xAy + -hh * xAx};
const botLeft = {x: -hw * xAx - hh * xAy, y: -hw * xAy + hh * xAx};
const topRight = {x: hw * xAx - -hh * xAy, y: hw * xAy + -hh * xAx};
const botRight = {x: hw * xAx - hh * xAy, y: hw * xAy + hh * xAx};
// Get the left top most corner
const left = Math.min(topLeft.x, botLeft.x, topRight.x, botRight.x);
const top = Math.min(topLeft.y, botLeft.y, topRight.y, botRight.y);
// Return the bounding box
return {
left: left + centerX,
top: top + centerY,
width: -left * 2,
height: -top * 2,
};
}
function animLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
rot += 0.01;
const bounding = drawRect(width, height, centerX, centerY, rot);
ctx.globalCompositeOperation = "destination-over";
ctx.fillStyle = "#F00";
ctx.fillRect(bounding.left, bounding.top, bounding.width, bounding.height);
ctx.globalCompositeOperation = "source-over";
requestAnimationFrame(animLoop);
}
<canvas id="canvas" width="400" height="180"></canvas>