Javascript 在画布中绘制旋转的圆角矩形,而不使用canvas.rotate()

Javascript 在画布中绘制旋转的圆角矩形,而不使用canvas.rotate(),javascript,html,canvas,Javascript,Html,Canvas,我使用了方形曲线在画布上绘制圆角矩形 现在我得到了矩形的(x1,y1),(x2,y2),(x3,y3),(x4,y4)四个点, 并希望在画布中绘制旋转的圆角矩形,而不使用canvas.rotate() 角点是此代码的错误位置,使用x1-x4、y1-y4而不使用canvas.rotate()绘制旋转圆角矩形的任何解决方案?我确信我的x1-x4、y1-y4工作正常。变换坐标 要旋转长方体,需要在每个点上应用旋转矩阵 矩阵 矩阵定义x轴(顶部)和y轴(像素的右侧,包括比例或像素的大小),以及原点的

我使用了方形曲线在画布上绘制圆角矩形

现在我得到了矩形的(x1,y1),(x2,y2),(x3,y3),(x4,y4)四个点, 并希望在画布中绘制旋转的圆角矩形,而不使用canvas.rotate()

角点是此代码的错误位置,使用x1-x4、y1-y4而不使用canvas.rotate()绘制旋转圆角矩形的任何解决方案?我确信我的x1-x4、y1-y4工作正常。

变换坐标 要旋转长方体,需要在每个点上应用旋转矩阵

矩阵 矩阵定义x轴(顶部)和y轴(像素的右侧,包括比例或像素的大小),以及原点的位置(坐标
{x:0,y:0}

转变 将坐标
x
y
转换为
tx
ty

   const x = ?
   const y = ?
   var tx, ty;
…首先沿x轴单独移动它

   tx = x * matrix[0]
   ty = x * matrix[1]
。。。同时沿x轴对其进行缩放。然后沿y轴移动并缩放

   tx += y * matrix[2]
   ty += y * matrix[3]
然后移到原点

   tx += matrix[4]
   ty += matrix[5]
此转换将坐标从局部空间移动到世界空间(或在二维世界空间中通常称为视图)

局部空间 旋转形状时,需要拾取要围绕其旋转的点,例如中心或一个角

为此,可以相对于旋转点(在形状的局部空间中)定义形状。例如,如果要围绕中心旋转长方体,请将左上角点和右下角点定义为与零的距离相等,例如
[-100,-50]
[100,50]

若要在角点处旋转,请相对于该角点放置长方体。例如,左上方的框是
[0,0]
[200100]

通过设置矩阵原点(画布上旋转中心的位置),可以在世界空间中定位形状

例子 如果我们知道比例是一致的(x轴和y轴的比例相同),并且x轴和y轴始终彼此成90度,则可以简化上述矩阵计算

该示例使用一个数组来保存矩阵、函数

  • transformPoint
    将矩阵应用于点
  • setOrigin
    设置变换原点(画布上旋转点所在的位置)
  • setRotation
    设置x轴和y轴的方向
  • setScale
    未在示例中使用。设置变换的比例。注意:在本例中,在
    setRotation
    之后必须调用
    setScale
  • setTransform
    未在示例中使用。以上三个问题是否在一次通话中解决
  • roundRect
    绘制形状,在局部空间中为其指定框的左上角和右下角坐标。它将角半径限制为最小尺寸,以适应并保持(接近贝塞尔曲线从不圆)圆角
有两个框用于演示如何更改旋转中心。一个绕中心旋转,另一个绕左上角旋转

第三个框(红色)表明没有理由手动转换框,使用2D API转换是相同的,但要简单得多,而且速度要快得多

requestAnimationFrame(更新);
const ctx=canvas.getContext(“2d”);
常数矩阵=[1,0,0,1,0,0];
函数变换点(x,y){
常数m=矩阵;
返回[x*m[0]+y*m[2]+m[4],x*m[1]+y*m[3]+m[5];
}
函数集合原点(x,y){
矩阵[4]=x;
矩阵[5]=y;
}
功能设置旋转(角度){
常数ax=数学cos(角度);
常数ay=数学sin(角度);
矩阵[0]=ax;
矩阵[1]=ay;
矩阵[2]=-ay;
矩阵[3]=ax;
}
功能设置刻度(刻度){
矩阵[0]*=标度;
矩阵[1]*=标度;
矩阵[2]*=标度;
矩阵[3]*=标度;
}
函数集变换(ox、oy、rot、scale){
常数ax=数学cos(rot)*标度;
const ay=数学sin(rot)*标度;
矩阵[0]=ax;
矩阵[1]=ay;
矩阵[2]=-ay;
矩阵[3]=ax;
矩阵[4]=ox;
矩阵[5]=oy;
}
函数roundRect(x1,y1,x2,y2,r,color=“#000”,线宽=2){
ctx.strokeStyle=颜色;
ctx.lineWidth=线宽;
常数min=Math.min(Math.abs(x1-x2),Math.abs(y1-y2));
r=r>min?min/2:r;
ctx.beginPath();
移动到(…转换点(x2-r,y1));
四次曲线(…相变点(x2,y1),…相变点(x2,y1+r));
ctx.lineTo(…转换点(x2,y2-r));
四次曲线(…变换点(x2,y2),…变换点(x2-r,y2));
ctx.lineTo(…转换点(x1+r,y2));
四次曲线(…相变点(x1,y2),…相变点(x1,y2-r));
ctx.lineTo(…转换点(x1,y1+r));
四次曲线(…相变点(x1,y1),…相变点(x1+r,y1));
ctx.closePath();
ctx.stroke();
}
函数roundRectAPITransform(x1,y1,x2,y2,r,color=“#F00”,线宽=2){
ctx.strokeStyle=颜色;
ctx.lineWidth=线宽;
常数min=Math.min(Math.abs(x1-x2),Math.abs(y1-y2));
r=r>min?min/2:r;
ctx.beginPath();
ctx.moveTo(x2-r,y1);
ctx.二次曲线(x2,y1,x2,y1+r);
ctx.lineTo(x2,y2-r);
四次曲线(x2,y2,x2-r,y2);
ctx.lineTo(x1+r,y2);
四次曲线(x1,y2,x1,y2-r);
ctx.lineTo(x1,y1+r);
ctx.二次曲线(x1,y1,x1+r,y1);
ctx.closePath();
ctx.stroke();
}
功能更新(时间){
clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
//围绕中心
setOrigin(100100);
setRotation(time*Math.PI/2000);//每4秒旋转一次
roundRect(-60,-35,60,35,15);
//在右上角
setOrigin(300100);
setRotation(-time*Math.PI/2000);//每4秒旋转一次
roundRect(-60,0,0,35,5);
//红波
   tx = x * matrix[0]
   ty = x * matrix[1]
   tx += y * matrix[2]
   ty += y * matrix[3]
   tx += matrix[4]
   ty += matrix[5]