【问题标题】:Unskewed child not aligning未倾斜的孩子不对齐
【发布时间】:2023-03-10 08:12:01
【问题描述】:

注意:这个问题是关于输出的问题,不是关于任何形状的创建。


我最近创建了一个形状:

.prog {
    position: relative;
    top: 20px;
    width: 150px;
    height: 120px;
    background: green;
    display: inline-block;
    transform: skewY(20deg);
    transform-origin: 0% 100%;
    transition: 0.8s ease;
}
.prog:before {
    content: "";
    position: absolute;
    left: 150px;
    width: 150px;
    height: 120px;
    background: red;
    transform: skewY(-40deg);
    transform-origin: 0% 100%;
    transition: 0.8s ease;
}
<div class="prog "></div>

在上面的 sn-p 中,绿色的形状是.prog 元素,并且是倾斜的。红色的形状是:before第一个元素的伪元素。

我将.prog (skewY) 倾斜了 20 度。现在,我需要 :before 为 -20 度。为此,我首先必须对其进行调整。然后将其进一步倾斜 20 度。
所以最终的skewY 值将是-40deg。我应用了这个,并且适当的transform-origins。

但问题是两个形状的顶点没有对齐。他们应该,但他们不是。这是显示问题的图像:

黑线仅供参考。

现在更多!

我歪曲了-20 -20 而不是-40

transform: skewY(-20deg) skewY(-20deg); <-- 这行得通!
transform: skewY(-40deg); <---------------- 这不行!

【问题讨论】:

    标签: css css-shapes css-transforms


    【解决方案1】:

    “未倾斜”孩子的行为是正常的,这是倾斜的工作方式。为了理解这一点,我将把问题简化为:

    为什么skewX(40deg)skewX(20deg) skewX(20deg) 不一样?

    div {
        width: 100px; height: 100px;
        position:absolute;
        top:20px; left:20px;
        transform-origin: 0 0;
    }
    .d1 {
        transform: skewX(40deg);
        background: red;
        opacity:0.7;
    }
    .d2 {
        transform: skewX(20deg) skewX(20deg);
        background: blue;
        opacity:0.7;
    }
    /** FOR THE DEMO **/
    body {background: url('http://i.stack.imgur.com/GySvQ.png');background-size: 10px;}
    .m {text-align:right;padding-top:105px;}
    .m1{width:83px;color:red;border-right:1px solid red;}
    .m2 {width:72px;color:blue;border-right:1px solid blue;}
    p{margin:0 0 5px 150px;color:red;}
    .b{color:blue;}
    <div class="d1"></div>
    <div class="d2"></div>
    <div class="m m1">x = 83</div>
    <div class="m m2"><br/>x = 72</div>
    <p class="r">skewX(40deg)</p>
    <p class="b">skewX(20deg) skewX(20deg)</p>

    注意:为了便于解释,我将使用100*100 方形 div,并且变换原点设置在该 div 的左上角。就像上面的代码sn-p一样。


    要了解这两种转换之间的区别,我们需要探索 CSS skew() 函数的工作方式。 The specs 说:

    沿 X 轴的 2D 倾斜变换,参数为 alpha 相当于矩阵:

    所以这意味着我们可以像这样计算 2D X 倾斜元素的每个点的坐标:

    | 1 tan(α) | . | x |
    | 0   1    |   | y |
    
    • α 是 X 倾斜角
    • x/y变换前点的坐标

    对于 skewX(40deg)

    α = tan(40deg) ~= 0.83
    
    | 1  0.83 | . | 0   |   | 83  |
    | 0  1    |   | 100 | = | 100 |
    

    新坐标是 x = 83,如代码 sn-p 示例所示。


    对于 skewX(20deg) skewX(20deg)

    α = tan(20deg) ~= 0.36
    

    第一次倾斜:

    | 1  0.36 | . | 0   |   | 36  |
    | 0  1    |   | 100 | = | 100 |
    

    第二个偏斜:

    | 1  0.36 | . | 36  |   | 72  |
    | 0  1    |   | 100 | = | 100 |
    

    新坐标是 x = 72,如代码 sn-p 所示。


    结论

    两种转换都不会给出相同的结果。所以skewY(20deg) skewY(-40deg)skewY(-20deg) 的转换不同,红色和绿色元素的两个顶角不能对齐为:

    tan(20deg) != tan(40deg)/2 
    

    参考资料:

    【讨论】:

      【解决方案2】:

      skew 引入了一个等于角度正切的垂直偏移量。因此,skew(20deg) 引入了 tan(20deg) 的偏移量。

      为了让你的例子起作用,应该是这样的

      tan(-20deg) = tan(20deg) + tan( -2 * 20deg)
      

      tan (2 * x) = 2 * tan (x)
      

      但这不是真的,切线和和不是关联的

      扭转它所需的偏斜是

      result = - atan ( 2 * tan (x))
      

      对于 x = 20,给出的结果为

      36,052388732387908475278040193987

      (大约)

      【讨论】:

        【解决方案3】:

        通过对产生输出而不是解释的最初答案的修订,我会假设*看到效果是因为您猜测是否定的skew 可用于偏移正偏斜曲线上的某个位置,而实际上,在负偏斜曲线上是负值。

        这首先要求偏斜的度量是奇异的并且发生在同一条曲线上(参见下面的正常曲线),正值和负值允许沿曲线移动。

        但是,负偏斜和正偏斜的曲线是反向的。

        零偏斜是唯一在两者上作用相同的值。因此,如果你有一个元素,对它应用 20 度的倾斜,然后应用负 20 的倾斜,你实际上会有一个零倾斜(正或负),所以使用负偏移 出现 em> 工作..

        但是,如果您随后应用额外的负偏斜,您将拥有一个负偏斜元素,其曲线不同且不等于正偏斜曲线上的反向等效位置。

        20deg = 原始元素,正倾斜曲线上的 20deg

        20deg - 20deg = 0,正负倾斜曲线相同

        -40deg = 取元素当前 20 度偏斜,负偏斜曲线上的负 40 度 = 20 度 - 不是正偏斜曲线上的等效“相反”点

        使用伪时,偏斜有效,因为您没有用新的偏斜量抵消正偏斜值。

        *我不是数学家,所以害怕我只能声称这是猜想

        【讨论】:

        • @SW4 这个问题我是故意的!如果您使用两个不同的别名,那么负角 确实 起作用! :jsfiddle.net/ThePragmatick/nb5teLen
        • 啊哈!在那种情况下,我想这对我有影响,嗯;)干得好,伙计们-我的坏:S
        • 我不认为统计上下文中的偏斜与图形偏斜直接可比
        • @vals,肯定会使用底层数学来计算转换吗?也就是说,如上所述,我不是数学家:)
        【解决方案4】:

        我将只解决主要问题,即为什么会发生这种情况,而不是尝试提供替代方案

        由于您的数学看起来很准确,我们必须搜索不准确的地方,即平台本身...

        MDN's article on transform 表示它不是一种稳定的技术:

        这是一项实验性技术
        由于该技术的规范尚未稳定,请检查

        (强调我的)

        考虑以下几点:

        当你倾斜主 div 时,它需要大量的浏览器渲染计算才能在 2D 环境中显示考虑到两个 3 轴的样子......伪元素会受到这些计算的影响,你可以看到你把它从你放置它的边缘再往左一点:

        根据应用于主 div 的 Y 倾斜,看到我刚刚向左移动,导致它向下一点。现在,当您重新倾斜伪元素时,再加上另外大量的计算...浏览器将无法提供 3D 空间在 2D 环境中的准确呈现...

        【讨论】:

        • 您的演示提供了一些见解。我认为正确解释所需的数学比最初看起来更微妙。
        • 我其实很讨厌这个浏览器无法处理答案...但是我缺乏正确的数学知识来获得更详细的答案...:/跨度>
        • 我以为 skewY()skewX() 不涉及 3D 计算
        • @web-tiki - 据我从 W3 规范中了解到,每个 transform 属性最终都是用 CTM(当前转换矩阵)计算的,它设置了一个 3D 上下文...... dev.w3.org/csswg/css-transforms/#3d-transform-rendering
        • 你的最后一个例子,红色元素下降一点,是根据规范所需的结果。浏览器在这里没有失败。
        猜你喜欢
        • 2014-05-21
        • 2017-12-15
        • 1970-01-01
        • 1970-01-01
        • 2019-12-15
        • 2013-02-01
        • 2023-03-19
        • 1970-01-01
        • 2021-09-18
        相关资源
        最近更新 更多