我真的需要了解skew(xdeg)
函数如何工作所有的研究似乎都没有解释x角度如何影响其他点并扭曲它,我需要知道它是否有任何数学公式或者是一种能够期望结果的方法使用特定学位。
PS。我已经阅读了大量的文档,其中最好的一个是DevDocs
该变换是剪切映射(横向),其将元素内的每个点在水平和垂直方向上扭曲一定角度。每个点的坐标由与指定角度成比例的值和到原点的距离修改;因此,距离原点越远,其附加值就越大。
但没有进一步解释给定角度将如何影响元素中的那些点。
在SVG书中,它通过说它按特定值推动水平或垂直线来解释偏斜,但我不知道deg
值如何被转换为偏移一个
应用于mathematical operation的<angle>
只是tan(<angle>)
。然后将其插入转换矩阵中。
好吧,这并没有真正深入探讨skew
,也不是为什么使用角度而不是数字因素是有意义的。因此,让我们采用以下ASCII示例来显示仅x偏斜。
skewX(0) skewX(45deg)
_| |_ _| |_ => original box markers
a o o o o a o o o o
b o o o o b o o o o
c o x o o c o x o o <-- this line didn't move
d o o o o d o o o o
e o o o z e o o o z
| | | |
因此,如果我们应用tan(45deg)
,它会给我们一个skewX因子1。
这意味着所有水平线将与转换原点的距离偏移1 *。
在上面的例子中,变换原点是5 * 5图像的中心(x
)。
因此第一个像素线(a o o o o
)与原点相距两个像素的距离,它将在左侧转换为2px。
最后一行(e o o o z
)距离原点+ 2px,它将在右边翻译2px。
位于原点的中间线(c o x o o
)不会受到此变换的影响。
好吧,但这仍然无法解释为什么要用角度而不是因素...
那么角度符号也是有意义的,因为我们也可以解释我们的例子,因为我们使用它们的中心点作为锚点将每列旋转45度。
即使只是我自己的推测,角度还有额外的好处,允许skewN(90deg)
状态无法用数字因子表示。
要理解skew
是如何工作的,让我们将它与另一个使用角度的变换进行比较。
这是一个旋转的例子,我们将变换原点设为top left
,然后由45deg
旋转:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:rgba(255,0,0,0.5);
transform-origin:top left;
transform:rotate(45deg);
}
<div class="box">
<div></div>
</div>
对于这个例子,找到角度及其工作原理在某种程度上是微不足道的:
现在让我们采用相同的示例,将旋转元素的高度降低到一个较小的值:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:3px;
width:100%;
background:red;
transform-origin:top left;
transform:rotate(45deg);
}
<div class="box">
<div></div>
</div>
这就像我们有一条旋转线。现在让我们用skew替换rotate:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:3px;
width:100%;
background:red;
transform-origin:top left;
transform:skewY(45deg);
}
<div class="box">
<div></div>
</div>
如果我们比较两个结果,我们会注意到在两种情况下我们都有某种旋转但是在倾斜变换时它们的大小不同:
现在更清楚的是角度是如何偏斜的。变换是一种依赖于角度来定义这种失真的失真。这是一个更好的例子:
蓝色是我们的初始元素,十字架是变换原点,黄色是角度。如果我们进行旋转,我们将获得宽度保持不变的红线。如果我们做一个倾斜,我们将获得宽度将改变的橙色线,并考虑到它将等于W / cos(angle)
其中W
是我们的初始宽度(在我们之前的情况下cos(45deg) = 1 / sqrt(2)
所以我们将有W * sqrt(2)
)。
那么我们的初始广场怎么样,它会如何表现出歪斜?
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform-origin:top left;
transform:skewY(45deg);
}
<div class="box">
<div></div>
</div>
它的行为与我们之前逐行描述的完全相同。如果我们在另一个方向上应用偏斜,我们也会得到相同的结果:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform-origin:top left;
transform:skewX(45deg);
}
<div class="box">
<div></div>
</div>
应用相同的逻辑但是垂直线并考虑高度。作为旁注,skewX(V)
与skew(V)
ref相同。
现在,如果我们在两个方向都应用偏斜:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform-origin:top left;
transform:skew(45deg,10deg);
}
<div class="box">
<div></div>
</div>
这就像我们首先应用skewX
扭曲垂直线然后我们将skewY
应用于新形状以扭曲水平线(或相反)。这是一个动画来说明skew(45deg,45deg)
的神奇结果:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform-origin:top left;
transform:skew(45deg,10deg);
animation:change 5s infinite alternate linear;
}
@keyframes change {
from {
transform:skew(0deg,0deg);
}
50% {
transform:skew(45deg,0deg);
}
to {
transform:skew(45deg,45deg);
}
}
<div class="box">
<div></div>
</div>
原点怎么样?转换没有任何改变,只有参考会改变。换句话说,固定点将移动:
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform-origin:center;
transform:skew(45deg,10deg);
animation:change 5s infinite alternate linear;
}
@keyframes change {
from {
transform:skew(0deg,0deg);
}
50% {
transform:skew(45deg,0deg);
}
to {
transform:skew(45deg,45deg);
}
}
<div class="box">
<div></div>
</div>
我们也可能注意到,如果我们在一个方向上倾斜,则只考虑transform-origin
的一个参数。
所以对于skewX
来说,transform-origin: X Y
将与X
的价值相同。这在某种程度上解释了逐行转换,因为当我们在线时,我们有一个维度。
.box {
margin:50px;
width:200px;
height:200px;
background:blue;
}
.box > div {
height:100%;
width:100%;
background:red;
transform:skewX(45deg);
animation:change 5s infinite alternate linear;
}
@keyframes change {
from {
transform-origin:0 0;
}
50% {
transform-origin:100% 0;/*nothing will happen between 0 and 50%*/
}
to {
transform-origin:100% 100%;
}
}
<div class="box">
<div></div>
</div>
更深入
现在让我们考虑矩阵计算,以了解它是如何使用的,以及如何使用tan(angle)
。
如果我们提到the documentation,我们有:
该矩阵用于基于逐点的初始元素的坐标来定义变换元素的坐标。考虑到这个定义,我们将得到这些方程式
Xf = Xi + Yi * tan(ax)
Yf = Xi * tan(ay) + Yi
如果我们考虑skewY
只是很明显ax
将是0
因此tan(0)
将是0
和X
将不会改变我们的第一个例子,我们只有Y轴失真(如果我们只应用skewY相同的逻辑)。
现在,为什么我们有Yf = Xi * tan(ay) + Yi
?
让我们重新看一下前面的插图:
绿点是由Xi,Yi
定义的初始点,红点是由Xf,Yf
定义的转换点。这是微不足道的Xf=Xi
和两点之间的距离将是Yf-Yi
。
考虑到插图,我们可以清楚地说,tan(ay) = (Yf-Yi)/Xi = (Yf-Yi)/Xf
因此我们将:
Xf = Xi
Yf = Xi * tan(ay) + Yi
如果我们在另一个方向上有偏差,我们应用相同的逻辑。