要了解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>
就像我们有一条旋转的线。现在让我们用倾斜替换旋转:
.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 是我们的初始宽度(在我们之前的例子中是@987654344 @ 所以我们会有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
如果我们向另一个方向倾斜,我们会应用相同的逻辑。