Javascript 如何仅使用转换旋转html画布形状?
我想知道如何只使用变换函数旋转图像。根据我的理解,这是不可能的,因为使用transform只能执行以下操作:Javascript 如何仅使用转换旋转html画布形状?,javascript,html,canvas,rotation,transformation,Javascript,Html,Canvas,Rotation,Transformation,我想知道如何只使用变换函数旋转图像。根据我的理解,这是不可能的,因为使用transform只能执行以下操作: 水平缩放 水平倾斜 垂直倾斜 垂直缩放 水平移动 垂直移动 资料来源: 我看不出这些是如何旋转形状的,这是可能的吗。我认为这一定是可能的,因为旋转实际上是一种类型转换。您可以轻松地旋转图像。可以指定要应用旋转的角度 资料来源: img.a{ 变换:旋转(180度); } 您可以轻松旋转图像。可以指定要应用旋转的角度 资料来源: img.a{ 变换:旋转(180度); } 使用
- 水平缩放
- 水平倾斜
- 垂直倾斜
- 垂直缩放
- 水平移动
- 垂直移动
我看不出这些是如何旋转形状的,这是可能的吗。我认为这一定是可能的,因为旋转实际上是一种类型转换。您可以轻松地旋转图像。可以指定要应用旋转的角度 资料来源:
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轴是从左到右方向
上每个CSS像素的1个变换像素{x:1,y:0}
- y轴是从上到下方向
上每CSS像素1个变换像素{x:0,y:1}
- 原点位于像素位置{x:0,y:0}左上角
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);
}