未歪斜的孩子没有对齐

时间:2015-02-03 14:17:14

标签: css css3 css-shapes css-transforms

注意:此问题与输出有关,有关任何形状的创建。


我最近创建了一个形状:



.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>
&#13;
&#13;
&#13;

在上面的代码片段中,绿色形状是.prog元素,并且是倾斜的。红色形状是第一个元素的:before伪元素。

我将.prog(偏斜)偏向20度。现在,我需要:before为-20deg。为此,我首先不得不疏忽它。然后将它进一步倾斜20度 因此,最终skewY值将为-40deg。我应用了这个,并适用transform-origin s。

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

unskewed child not aligning

黑线仅供参考。

现在更多!

我偏向-20 -20而不是-40

transform: skewY(-20deg) skewY(-20deg); <--这有效!
transform: skewY(-40deg); <----------------这不是!

4 个答案:

答案 0 :(得分:12)

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

  

为什么skewX(40deg)skewX(20deg) skewX(20deg)不相同?

Difference between skewX(40deg) and 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的左上角。与上面的代码段一样。


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

  

沿X轴的2D歪斜变换,参数alpha为   相当于矩阵:skewX() matrix

所以这意味着我们可以像这样计算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 ,如代码段示例所示。


对于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 ,如代码段中所示。


结论

两种转换都不会产生相同的结果。因此skewY(20deg) skewY(-40deg)skewY(-20deg)的转换不同,红色和绿色元素的两个顶角无法对齐:

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

参考文献:

答案 1 :(得分:5)

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

(aproximately)

答案 2 :(得分:3)

通过修改我的初始答案产生输出而不是解释,我会假设 * 看到效果,因为你猜测是负面的偏斜可用于偏移正偏斜曲线上的位置,实际上 - 在负斜率曲线上操作负值时。

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

enter image description here

然而,负斜率和正斜率的曲线是反向尾的。

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

但是,如果再应用其他负偏斜,则会产生负偏斜元素,其曲线不同,不等于正偏斜曲线上的反向等效位置。

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

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

-40deg =在负偏斜曲线上取元素当前20度偏斜,减去40度= 20度 - 不等同于&#39;相反&#39;指向正偏斜曲线

使用伪造时,偏斜起作用,因为你没有将正偏斜的值偏移一个新的倾斜量。

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

答案 3 :(得分:2)

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

由于你的数学似乎是准确的,我们必须搜索不精确的东西,这是平台本身......

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

  

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

(强调我的)

请考虑以下事项:

当你倾斜主div时,它需要大量的浏览器渲染计算才能在2D环境中显示考虑两个轴的情况......伪元素会受到这些计算的影响,正如您所看到的那样你从它所放置的边缘稍微离开了一点:

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