为了理解
skew
是如何工作的,让我们将其与另一种使用角度的变换进行比较。
这里有一个旋转的示例,我们将变换原点设为
左上
,然后旋转
45度
:
.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>
对于这个例子,找到角度并理解它的工作原理有些微不足道:
![enter image description here](https://istack.dev59.com/pgfpg.webp)
现在让我们以同样的例子为基础,将旋转元素的高度减小到一个较小的值:
.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>
就像我们有一条旋转的线一样。现在让我们用倾斜来替换旋转:
.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>
如果我们比较两个结果,我们会注意到在两种情况下都存在旋转,但在斜变换的大小方面存在差异:
![enter image description here](https://istack.dev59.com/VUw2s.webp)
现在更清楚了,偏斜是如何与角度配合使用的。变换是一种依靠角度来定义这种扭曲的形变。这里有一个更好的说明:
![enter image description here](https://istack.dev59.com/Ea4x3.webp)
蓝色是我们的初始元素,十字是变换原点,黄色是角度。如果我们进行旋转,我们会得到红线,其中宽度保持不变。如果我们进行倾斜,我们将得到橙色线,其中宽度将会改变,考虑到插图,它将等于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
,无论
X
的值是什么,
transform-origin: X Y
都将相同。这在某种程度上解释了逐行转换,因为当我们有一行时,我们只有一个维度。
.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;
}
to {
transform-origin:100% 100%;
}
}
<div class="box">
<div></div>
</div>
更深入的了解
现在让我们考虑矩阵计算,以了解它的用法以及如何使用tan(angle)
。
如果我们参考文档,我们有:
![enter image description here](https://istack.dev59.com/CAjhE.webp)
这个矩阵用于根据初始元素的每个点的坐标来定义变换后元素的坐标。考虑到这一定义,我们会得到以下方程。
Xf = Xi + Yi * tan(ax)
Yf = Xi * tan(ay) + Yi
如果我们只考虑
skewY
,明显
ax
将为
0
,因此
tan(0)
将为
0
,
X
不会改变,这就是我们第一个例子中只在Y轴上扭曲的情况(如果我们仅应用skewY,则逻辑相同)。
现在,为什么我们有
Yf = Xi * tan(ay)+ Yi
?
让我们重新看之前的示例:
![enter image description here](https://istack.dev59.com/cbJZZ.webp)
绿点是由Xi,Yi
定义的初始点,红点是由Xf,Yf
定义的变换后的点。显然有Xf=Xi
,两点之间的距离为Yf-Yi
。
从图示中可以清楚地看到tan(ay) = (Yf-Yi)/Xi = (Yf-Yi)/Xf
,因此我们有:
Xf = Xi
Yf = Xi * tan(ay) + Yi
我们会应用相同的逻辑,如果我们在另一个方向上有偏斜。
transform
的计算值作为matrix()
函数返回的原因。所以实际上是rotate(∂)
被转换为cos(∂)、sin(∂)、-sin(∂)、cos(∂)、x、y)
。 - Kaiido