【问题标题】:skew() function in depthskew() 函数深入
【发布时间】:2019-02-04 20:46:48
【问题描述】:

我真的需要了解skew(xdeg) 函数的工作原理所有研究似乎都没有解释 x 角如何影响其他点并像那样扭曲它,我需要知道它是否有任何数学公式或方法能够预期使用特定学位的结果。

ps。我已经阅读了大量的文档,其中最好的一个是 DevDocs,上面写着

这种变换是一种剪切映射(横切面),它会扭曲 元素内的每个点在水平方向上的某个角度和 垂直方向。每个点的坐标由a修改 值与指定的角度和距离成比例 起源;因此,一个点离原点越远,意志越大 是它的附加值。

但没有进一步解释给定角度将如何影响元素中的这些点。

在 SVG 书中,它通过说它按特定值推动水平或垂直线来解释倾斜,但我不明白 deg 值是如何转换为偏移的

【问题讨论】:

    标签: html css css-transforms skew


    【解决方案1】:

    应用于<angle>mathematical operation 就是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),它会给我们一个 1 的 skewX 因子。
    这意味着所有水平线将被 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) 状态不能用数字因子表示。

    【讨论】:

    • @TemaniAfif 好吧...老实说,我认为您的答案顺序不正确;-) CSS 转换(如 SVG 和 canvas2D 顺便说一句)是从 3*3 转换矩阵完成的,所以最终,一切都只是 [scaleX, skewX, skewY, scaleY, translateX, translateY]。这就是为什么 transform 的计算值被重新调整为 matrix() 函数的原因。所以它实际上是rotate(∂),它被转换为cos(∂), sin(∂), -sin(∂), cos(∂), x, y)
    • @TemaniAfif 在我的印象中,css 语法已经从变换矩阵到倾斜函数,他们决定使用这种用户友好的符号。真正完成的动作不是旋转,所以我觉得从它开始有点误导。我个人认为从必须做的事情到我应该按下哪个按钮更容易理解。但无论如何,这两种观点都是有价值的,而且信息很重要。我们应该保持原样。
    【解决方案2】:

    要了解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 的一个参数。

    所以对于skewXtransform-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) 将是0X 不会改变,这是我们第一个示例的情况,我们只有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
    

    如果我们向另一个方向倾斜,我们会应用相同的逻辑。

    【讨论】:

      猜你喜欢
      • 2018-01-11
      • 2023-04-02
      • 2019-11-11
      • 2016-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-28
      相关资源
      最近更新 更多