我想创建一个沿其轴旋转正方形的函数。
var halfWidth = canvas.width/2;
var halfHeight = canvas.height/2;
var x = halfWidth-10;
var y = halfHeight-10;
var w = 20;
var h = 20;
var deg = 45;
rotate(x, y, w, h, deg);
ctx.fillRect(x, y, w, h);
功能:
function rotate(x, y, w, h, deg) {
// ctx.translate() and ctx.rotate()
// goes here.
}
如何做到这一点?
感谢dr.dredel提供链接。
var cx = canvas.width/2;
var cy = canvas.height/2;
var x = -10;
var y = -10;
var w = 20;
var h = 20;
var deg = 45;
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(deg * Math.PI/180);
ctx.fillRect(x, y, w, h);
ctx.restore();
说明:
ctx.save()
保存坐标系的当前状态。ctx.translate(cx, cy)
将原点更改为画布中心ctx.rotate(deg * Math.PI/180)
将正方形旋转45度(注意参数单位是弧度,而不是度)ctx.fillRect( x, y, w, h )
绘制正方形ctx.restore()
恢复坐标系最后的状态。如果您不想处理
ctx.save()
之类的问题,有一种简单的方法可以计算旋转正方形的每个新点应该在哪里。
下面会画一个绿色的正方形,然后画一个旋转了22.5°的红色正方形。
const ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(50, 50, 50, 50)
/**
*
* @returns {[number, number]} (x3, y3)
*/
function f(x1, y1, x2, y2, degrees) {
const rad = degrees * Math.PI / 180;
return [
(x2 - x1) * Math.cos(rad) + x1 - (y2 - y1) * Math.sin(rad),
(x2 - x1) * Math.sin(rad) + y1 + (y2 - y1) * Math.cos(rad)
]
}
ctx.fillStyle = "red";
const centre = 75;
/*
* The centre of the square is at (75, 75)
* The corner points are at:
* (50, 50)
* (100, 50)
* (100, 100)
* (50, 100)
*/
ctx.beginPath();
let [newX, newY] = f(centre, centre, 50, 50, 22.5);
ctx.moveTo(newX, newY);
[newX, newY] = f(centre, centre, 100, 50, 22.5);
ctx.lineTo(newX, newY);
[newX, newY] = f(centre, centre, 100, 100, 22.5);
ctx.lineTo(newX, newY);
[newX, newY] = f(centre, centre, 50, 100, 22.5);
ctx.lineTo(newX, newY);
[newX, newY] = f(centre, centre, 50, 50, 22.5);
ctx.lineTo(newX, newY);
ctx.fill();
<canvas width=200 height=200 style="background:gray"></canvas>
我将这张图放在一起,认为它可能有助于直观地了解正在发生的事情。
如果我没记错的话,涉及的平移类似于首先平移到矩形的中心点,然后旋转所需的量,然后绘制。或者可能先旋转,然后平移,我有点生疏=)
这是我的看法:
JAVASCRIPT
var canvas = document.getElementById("myCanvas");
var ctx2 = canvas.getContext("2d");
ctx2.fillStyle='#333';
ctx2.fillRect(50,50,100,100);
var ctx = canvas.getContext("2d");
ctx.fillStyle='red';
var deg = Math.PI/180;
ctx.save();
ctx.translate(100, 100);
ctx.rotate(45 * deg);
ctx.fillRect(-50,-50,100,100);
ctx.restore();
ctx2 是旧位置,ctx 是形状的新位置。您必须根据您想要放置形状的位置,使用相同的 x,y 坐标平移形状。然后,您必须输入值以保持 x 和 y 作为 -ve 值(高度和宽度的一半,以使其保持在画布的对角线上,否则进行更改以对其进行操作)。 h、w 作为您想要的值。
ctx.fillRect(x,y,w,h);
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function rd(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
for (let i = 0; i < 10; i++) {
drawRect(rd(0, 400), rd(0, 400))
}
function drawRotatedRect(x, y, width, height, degrees) {
// first save the untranslated/unrotated context
ctx.save();
ctx.beginPath();
// move the rotation point to the center of the rect
ctx.translate(x + width / degrees, y + height / degrees);
// rotate the rect
ctx.rotate(degrees * Math.PI / 180);
// draw the rect on the transformed context
ctx.rect(-width / 2, -height / 2, width, height);
ctx.fillStyle = "gold";
ctx.fill();
// restore the context to its untranslated/unrotated state
ctx.restore();
}
function drawRect(x, y) {
const squareSize = 50;
const degrees = 60;
// draw an unrotated reference rect
ctx.beginPath();
ctx.rect(x - squareSize/2, y - squareSize/2 , squareSize, squareSize);
ctx.fillStyle = "blue";
ctx.fill();
// draw a rotated rect
drawRotatedRect(x, y, squareSize, squareSize, degrees);
// draw center coord reference point
drawDot(x, y, 5)
}
function drawDot(x, y, size) {
ctx.beginPath();
ctx.arc(x , y, size, 0, 2 * Math.PI);
ctx.fillStyle = 'black'
ctx.fill();
}
canvas {
border:1px solid red;
}