Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何仅使用转换旋转html画布形状?_Javascript_Html_Canvas_Rotation_Transformation - Fatal编程技术网

Javascript 如何仅使用转换旋转html画布形状?

Javascript 如何仅使用转换旋转html画布形状?,javascript,html,canvas,rotation,transformation,Javascript,Html,Canvas,Rotation,Transformation,我想知道如何只使用变换函数旋转图像。根据我的理解,这是不可能的,因为使用transform只能执行以下操作: 水平缩放 水平倾斜 垂直倾斜 垂直缩放 水平移动 垂直移动 资料来源: 我看不出这些是如何旋转形状的,这是可能的吗。我认为这一定是可能的,因为旋转实际上是一种类型转换。您可以轻松地旋转图像。可以指定要应用旋转的角度 资料来源: img.a{ 变换:旋转(180度); } 您可以轻松旋转图像。可以指定要应用旋转的角度 资料来源: img.a{ 变换:旋转(180度); } 使用

我想知道如何只使用变换函数旋转图像。根据我的理解,这是不可能的,因为使用transform只能执行以下操作:

  • 水平缩放
  • 水平倾斜
  • 垂直倾斜
  • 垂直缩放
  • 水平移动
  • 垂直移动
资料来源:


我看不出这些是如何旋转形状的,这是可能的吗。我认为这一定是可能的,因为旋转实际上是一种类型转换。

您可以轻松地旋转图像。可以指定要应用旋转的角度

资料来源:


img.a{
变换:旋转(180度);
}

您可以轻松旋转图像。可以指定要应用旋转的角度

资料来源:


img.a{
变换:旋转(180度);
}
使用“旋转”变换,并按如下方式使用

p{
颜色:红色;
字体大小:12px;
文本对齐:居中;
}
.轮换1{
变换:旋转(45度);
边缘顶端:40px;
}
.轮换2{
变换:旋转(90度);
边缘顶端:40px;
}
.轮换3{
变换:旋转(180度);
边缘顶端:40px;
}

rotate1

rotate2

rotate3

使用变换“rotate”。并按如下方式使用它

p{
颜色:红色;
字体大小:12px;
文本对齐:居中;
}
.轮换1{
变换:旋转(45度);
边缘顶端:40px;
}
.轮换2{
变换:旋转(90度);
边缘顶端:40px;
}
.轮换3{
变换:旋转(180度);
边缘顶端:40px;
}

rotate1

rotate2

rotate3

2D变换基础 6个值作为3个向量 转换是一组6个数字。作为3对的6个数字表示x轴的方向和比例、y轴的方向和比例以及原点的位置

单位矩阵的缺省变换 默认转换(称为单位矩阵)的值为
ctx.setTransform(1,0,0,1,0,0)
,这意味着

  • x轴是从左到右方向
    {x:1,y:0}
    上每个CSS像素的1个变换像素
  • y轴是从上到下方向
    {x:0,y:1}
    上每CSS像素1个变换像素
  • 原点位于像素位置{x:0,y:0}左上角
缩放比例 如果我们缩放变换,我们会增加前两个向量的长度。按2缩放,变换为
ctx.setTransform(2,0,0,2,0,0)

  • x轴是x方向上每2个CSS像素的1个变换像素
    {x:2,y:0}
    从左到右
  • y轴是y方向上每2个CSS像素的1个变换像素
    {x:0,y:2}
    自上而下
  • 原点仍然位于左上方{x:0,y:0}
旋转和平移 如果我们想将256×256的正方形图像旋转90度,那么变换是
ctx.setTransform(0,1,-1,0,256,0)

  • x轴是y方向上每CSS像素1个变换像素
    {x:0,y:1}
  • y轴是在负x方向上每CSS像素1个变换像素
    {x:-1,y:0}
    从右到左
  • 原点(图像0,0将位于画布上的位置)是{x:256,y:0}
因此,如果我们运行

ctx.setTransform(0, 1, -1, 0, 256, 0);
ctx.drawImage(myImage, 0, 0, 256, 256); // will draw image rotated 90deg CW
我们得到一个旋转的图像

向量 向量是两个具有x和y值的值。向量定义了方向和长度

创建旋转的单位向量 要将方向转换为向量,我们使用正弦和余弦

const myDirection = angle;
const myDirectionAsRadians = angle * (Math.PI / 180);  // convert angle to radians

const x = Math.cos(myDirectionAsRadians)
const y = Math.sin(myDirectionAsRadians)
如果我们将
myDirection
设置为90度,则
x=0
y=1
指向画布

使用正弦和余弦可以在任何方向上创建向量。它有一个特殊的性质,它的长度总是1。我们称这种向量为单位向量。有时您可能会看到一个向量被规格化。这会将任意长度的向量转换为单位向量。这是通过将向量x和y除以其长度来完成的

 function normalize(vector) {
     const length = Math.hypot(vector.x, vector.y);
     vector.x /= length;
     vector.y /= length;
 }
注意长度为零的向量,例如
x:0,y:0
无法标准化。不是因为它没有长度(长度为0),而是因为它没有方向

缩放旋转向量 我们可以定义角度和比例

const myDirection = -90;
const myDirectionAsRadians = -90 * (Math.PI / 180);  // -90 as radians
const myScale = 2;

const x = Math.cos(myDirectionAsRadians) * myScale
const y = Math.sin(myDirectionAsRadians) * myScale
现在对于-90度,向量是
x=0
y=-2
指向上,两个CSS像素长

快速旋转矢量90度CW 对于均匀的缩放和旋转(图像总是正方形),我们只需要一个向量。例如,从上面
x=0
y=-2
(指向上)可以通过交换两个组件并对新的x求反来旋转90 CW。例如
xx=-y
y=x
以从左到右获得
xx=2
y=0
2个CSS像素。因此,我们有x轴和y轴的方向和比例。y轴始终与x轴保持90 CW

使用变换绘制 创建旋转和缩放变换 创建旋转任意角度和缩放任意量的变换的步骤

 function scaleAndRotate(scale, rotate) { // rotate is in radians
     // get direction and length of x axis
     const xAX = Math.cos(rotate) * scale;
     const xAY = Math.sin(rotate) * scale;
     // get direction and length of y axis that is 90 deg CW of x axis and same length
     const [yAX, yAY] = [-xAY, xAX];  // swap and negate new x

     // set the transform
     ctx.setTransform(xAX, xAY, yAX, yAY, 0, 0);

 }
画图 让我们创建一个函数,该函数将在画布上的任意位置绘制一个均匀旋转和缩放的图像。我们将使用图像的中心作为参考点

 function drawImageScaleRotate(img, x, y, scale, rotate) {
      // define the direction and scale of x axis
      const xAX = Math.cos(rotate) * scale;
      const xAY = Math.sin(rotate) * scale;

      // create the transform with yaxis at 90 CW of x axis and origin at x, y
      ctx.setTransform(xAX, xAY, -xAY, xAX, x, y);

      // Draw the image so that its center is at the new origin x, y
      ctx.drawImage(img, -img.width / 2, -img.height / 2);

   }
还有很多 当我们使用
ctx.setTranform
设置转换时,我们将替换现有的转换。此转换保持当前状态。如果我们使用
ctx.transform
ctx.rotate
ctx.scale
ctx.translate
将变换应用于当前变换,则可以分阶段构建变换

转换函数在CPU周期方面相对昂贵。也就是说,使用sin和cos构建矩阵比使用
ctx.scale
ctx.rotate
ctx.translate要快得多
 function drawImageScaleRotate(img, x, y, scale, rotate) {
      const xAX = Math.cos(rotate) * scale;
      const xAY = Math.sin(rotate) * scale;
      ctx.setTransform(xAX, xAY, -xAY, xAX, x, y);
      ctx.drawImage(img, -img.width / 2, -img.height / 2);
   }